摘要:FactorySupport Facility允许我们使用已经存在的工厂来创建组件的实例,可以把已经存在的对象模型加入到容器中,以便它能够使用自动装配。它使用了以下两种处理策略: 2 .为什么需要FactorySupport Facility FactorySupport Facility 允许我们使用已经存在的工厂来创建组件的实例,可以把已经存在的对象模型加入到容器中,以便它能够使用自动装配。它使用了以下两种处理策略: 二.为什么需要FactorySupport Facility
为了回答这个问题,我们先来看一个简单的使用工厂的例子,如下代码所示: public interface IComponent { void Display();} public class MyComponent : IComponent { public MyComponent() { } public void Display() { Console.WriteLine("MyComponent"); }} public class MyFactory { public MyFactory() { } public IComponent Create() { return new MyComponent(); }} 现在要在程序中使用 MyComponent的实例,简单一点会这样去写:
public class App { static void Main() { MyFactory factory = new MyFactory(); IComponent comp = factory.Create(); comp.Display(); }} 正如你所看到的,在程序中使用 new关键字创建了一个工厂的实例,再由工厂得到组件的实例。现在我们看使用 FactorySupport Facility后带来了什么好处。工厂和组件的代码不变,仍然是:
public interface IComponent { void Display();} public class MyComponent : IComponent { public MyComponent() { } public void Display() { Console.WriteLine("MyComponent"); }} public class MyFactory { public MyFactory() { } public IComponent Create() { return new MyComponent(); }} 配置文件,现在你可以不用理解怎么去配置,后面会讲到。
<? xml version="1.0" encoding="utf-8" ?> < configuration > < 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 > </ configuration > public class App { static void Main() { IWindsorContainer container = new WindsorContainer("../../Basic.xml"); IComponent instance = (IComponent) container["mycomp"]; instance.Display(); }} 看到了吗?我们并没有使用 new关键字创建任何对象,只是把工厂、组件等通过配置文件抛给了 IOC容器,再从容器中往外取的时候,就可以直接取到组件的实例,这些实例是由工厂自动创建的,这正是 FactorySupport Facility的作用。
知道了为什么需要FactorySupport Facility之后,下面就来看如何使用Facility。在前面的代码中大家都已经看到了,使用FactorySupport Facility是非常的简单。 1 .加入FactorySupport Facility到容器中,可以使用代码加入也可以使用配置文件。 IWindsorContainer container = new WindsorContainer( " ../../Basic.xml " );container.AddFacility( " factorysupport " , new Castle.Facilities.FactorySupport.FactorySupportFacility()); < facilities > < facility id ="factorysupport" type ="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" /> </ facilities > < component id ="accessor.comp" type ="Castle.Facilities.FactorySupport.Tests.Components.SingletonWithAccessor, Castle.Facilities.FactorySupport.Tests" instance-accessor ="Instance" > </ component > < component id ="mycomp" type ="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests" factoryId ="mycompfactory" factoryCreate ="Create" > </ component > 这是一些常见的配置示例,来自于Castle自带的测试代码中。 public class SingletonWithAccessor { private static readonly SingletonWithAccessor instance = new SingletonWithAccessor(); private SingletonWithAccessor() { } public static SingletonWithAccessor Instance { get { return instance; } }} <? xml version="1.0" encoding="utf-8" ?> < configuration > < facilities > < facility id ="factorysupport" type ="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" /> </ facilities > < components > < component id ="accessor.comp" type ="Castle.Facilities.FactorySupport.Tests.Components.SingletonWithAccessor, Castle.Facilities.FactorySupport.Tests" instance-accessor ="Instance" ></ component > </ components > </ configuration > public class MyComp { public MyComp() { }} public class MyCompFactory { public MyComp Create() { return new MyComp(); }} <? xml version="1.0" encoding="utf-8" ?> < configuration > < facilities > < facility id ="factorysupport" type ="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" /> </ facilities > < components > < component id ="mycompfactory" type ="Castle.Facilities.FactorySupport.Tests.Components.MyCompFactory, Castle.Facilities.FactorySupport.Tests" /> < component id ="mycomp" type ="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests" factoryId ="mycompfactory" factoryCreate ="Create" ></ component > </ components > </ configuration > public class MyComp { private string storeName; private IDictionary props; internal MyComp() { } internal MyComp(String storeName, IDictionary props) { this.storeName = storeName; this.props = props; } public string StoreName { get { return storeName; } } public IDictionary Props { get { return props; } }} public class MyCompFactory2 { public MyCompFactory2() { } public MyComp Create(String storeName, IDictionary props) { return new MyComp(storeName, props); }} <? xml version="1.0" encoding="utf-8" ?> < configuration > < facilities > < facility id ="factorysupport" type ="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" /> </ facilities > < components > < component id ="mycompfactory" type ="Castle.Facilities.FactorySupport.Tests.Components.MyCompFactory2, Castle.Facilities.FactorySupport.Tests" ></ component > < component id ="mycomp" type ="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests" factoryId ="mycompfactory" factoryCreate ="Create" > < parameters > < storeName > MyStore </ storeName > < props > < dictionary > < entry key ="key1" > item1 </ entry > < entry key ="key2" > item2 </ entry > </ dictionary > </ props > </ parameters > </ component > </ components > </ configuration > public interface IMyService { } public class MyComp { private IMyService serv; internal MyComp() { } internal MyComp(IMyService serv) { this.serv = serv; } public IMyService Service { get { return serv; } }} public class MyCompFactory3 { public MyCompFactory3() { } public MyComp Create(IMyService serv) { return new MyComp(serv); }} <? xml version="1.0" encoding="utf-8" ?> < configuration > < facilities > < facility id ="factorysupport" type ="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" /> </ facilities > < components > < component id ="myserv" service ="Castle.Facilities.FactorySupport.Tests.Components.IMyService, Castle.Facilities.FactorySupport.Tests" type ="Castle.Facilities.FactorySupport.Tests.Components.DefaultMyService, Castle.Facilities.FactorySupport.Tests" /> < component id ="mycompfactory" type ="Castle.Facilities.FactorySupport.Tests.Components.MyCompFactory3, Castle.Facilities.FactorySupport.Tests" ></ component > < component id ="mycomp" type ="Castle.Facilities.FactorySupport.Tests.Components.MyComp, Castle.Facilities.FactorySupport.Tests" factoryId ="mycompfactory" factoryCreate ="Create" > <!-- parameters is not necessary_u97 ?s it will auto wire --> </ component > </ components > </ configuration > FactorySupport Facility 的实现也是非常的简单,主要是通过两个 ComponentActivator 来实现,分别为AccessorActivator和FactoryActivator,根据配置文件的不同调用不同的Activator。 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);} 好了,关于 FactorySupport Facility就介绍到这儿,更多 Castle的文章您可以访问《 》。
本文转自lihuijun51CTO博客,原文链接: http://blog.51cto.com/terrylee/67692 ,如需转载请自行联系原作者