FactorySupport Facility 允許使用現有工廠建立組件實例,將既有物件模型納入容器自動裝配體系。支援兩種策略:
傳統寫法:程式碼中直接 new 工廠再取得組件,產生硬性依賴。
public class App {
static void Main() {
MyFactory factory = new MyFactory();
IComponent comp = factory.Create();
comp.Display();
}
}
使用 Facility 後:工廠與組件代碼不變,透過配置檔交給容器管理:
<facilities>
<facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
</facilities>
<components>
<component id="myfactory" type="FactorySupportDemo.MyFactory, FactorySupportDemo" />
<component id="mycomp" type="FactorySupportDemo.MyComponent, FactorySupportDemo"
factoryId="myfactory" factoryCreate="Create"></component>
</components>
public class App {
static void Main() {
IWindsorContainer container = new WindsorContainer("../../Basic.xml");
IComponent instance = (IComponent)container["mycomp"];
instance.Display(); // 完全無 new 關鍵字
}
}
// 程式碼方式
container.AddFacility("factorysupport", new FactorySupportFacility());
// 配置檔方式
<facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" />
instance-accessor="Instance"factoryId="myfactory" factoryCreate="Create"public class SingletonWithAccessor {
private static readonly SingletonWithAccessor instance = new SingletonWithAccessor();
private SingletonWithAccessor() {}
public static SingletonWithAccessor Instance { get { return instance; } }
}
<component id="accessor.comp" type="...SingletonWithAccessor,..." instance-accessor="Instance"></component>
<component id="mycompfactory" type="...MyCompFactory,..." />
<component id="mycomp" type="...MyComp,..." factoryId="mycompfactory" factoryCreate="Create"></component>
<component id="mycompfactory" type="...MyCompFactory2,..."></component>
<component id="mycomp" type="...MyComp,..." factoryId="mycompfactory" factoryCreate="Create">
<parameters>
<storeName>MyStore</storeName>
<props>
<dictionary>
<entry key="key1">item1</entry>
<entry key="key2">item2</entry>
</dictionary>
</props>
</parameters>
</component>
<component id="myserv" service="...IMyService,..." type="...DefaultMyService,..." />
<component id="mycompfactory" type="...MyCompFactory3,..."></component>
<component id="mycomp" type="...MyComp,..." factoryId="mycompfactory" factoryCreate="Create"></component>
容器自動解析 IMyService 傳給工廠 Create 方法。
根據配置決定使用 AccessorActivator 或 FactoryActivator:
string instanceAccessor = model.Configuration.Attributes["instance-accessor"];
string factoryId = model.Configuration.Attributes["factoryId"];
string factoryCreate = model.Configuration.Attributes["factoryCreate"];
if (instanceAccessor != null) {
model.ExtendedProperties.Add("instance.accessor", instanceAccessor);
model.CustomComponentActivator = typeof(AccessorActivator);
} else if (factoryId != null) {
model.ExtendedProperties.Add("factoryId", factoryId);
model.ExtendedProperties.Add("factoryCreate", factoryCreate);
model.CustomComponentActivator = typeof(FactoryActivator);
}
更多 Castle 系列文章請參考《Castle 開發系列文章》。