注冊方式較多,大體有這么幾種,學習得比較粗淺,先記錄:
1、逐個注冊組件
即對每個接口通過代碼指定其實現類,代碼:
典型應用場景:例如定義了一個日志記錄接口,放到一個獨立程序集中。具體實現可能有多種方式(日志以文本文件/XML文件/數據庫等不同方式存儲),則可以為每個實現類建立一個獨立的程序集,在各程序集中將自身注冊為接口的實現。這樣當我們需要日志的某個存儲形式時,選擇對應的dll即可
2、按規則批量注冊
和1比較類似,不同的是,不用逐個指定接口和實現類,而是指定一個規則,Windsor會用規則去匹配和注冊當前應用中所有程序集。代碼:
3、按程序集安裝注冊
與按照規則批量注冊類似,差別在於每個程序集內部自己實現一個IWindsorInstaller接口來定義注冊規則。也就是將注冊規則下放到程序集。
首先,需要指定對哪些程序集進行安裝注冊(只指定對程序集的搜索規則):
container.Install(FromAssembly.InDirectory(new AssemblyFilter("Extensions")));//Extensions目錄下的所有程序集。
其次,每個程序集內通過一個或多個實現了IWindsorInstaller接口的類,來定義哪些Interface和實現類要注冊到容器。
如下代碼是官網上的一個范例:
意思是當前程序集中,與RepositoriesInstaller具有相同命名空間的接口、實現,都注冊到IOC容器中。
4、XML配置文件注冊
用構造函數方式注冊:
或通過Install方法
二、
1、逐個注冊組件
即對每個接口通過代碼指定其實現類,代碼:
container.Register( Component.For<IMyService>() //接口 .ImplementedBy<MyService>() //實現類 );
典型應用場景:例如定義了一個日志記錄接口,放到一個獨立程序集中。具體實現可能有多種方式(日志以文本文件/XML文件/數據庫等不同方式存儲),則可以為每個實現類建立一個獨立的程序集,在各程序集中將自身注冊為接口的實現。這樣當我們需要日志的某個存儲形式時,選擇對應的dll即可
2、按規則批量注冊
和1比較類似,不同的是,不用逐個指定接口和實現類,而是指定一個規則,Windsor會用規則去匹配和注冊當前應用中所有程序集。代碼:
container.Register(Classes.FromThisAssembly() //當前程序集,也可以調用其它方法,如FromAssemblyInDirectory()等 .InSameNamespaceAs<RootComponent>() //與RootComponent類具有相同的命名空間,還可以用InNamespace("Com.Spbdev")直接指定命名空間 .WithService.DefaultInterfaces() .LifestyleTransient()); //生命周期
3、按程序集安裝注冊
與按照規則批量注冊類似,差別在於每個程序集內部自己實現一個IWindsorInstaller接口來定義注冊規則。也就是將注冊規則下放到程序集。
首先,需要指定對哪些程序集進行安裝注冊(只指定對程序集的搜索規則):
container.Install(FromAssembly.InDirectory(new AssemblyFilter("Extensions")));//Extensions目錄下的所有程序集。
其次,每個程序集內通過一個或多個實現了IWindsorInstaller接口的類,來定義哪些Interface和實現類要注冊到容器。
如下代碼是官網上的一個范例:
public class RepositoriesInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register(Classes.FromThisAssembly() .Where(Component.IsInSameNamespaceAs<RepositoriesInstaller>()) .WithService.DefaultInterfaces() .LifestyleTransient()); } }
意思是當前程序集中,與RepositoriesInstaller具有相同命名空間的接口、實現,都注冊到IOC容器中。
4、XML配置文件注冊
用構造函數方式注冊:
IWindsorContainer container = new WindsorContainer("dependencies.config");
或通過Install方法
container.Install( Configuration.FromXmlFile("dependencies.config"));
二、
安裝的配置
安裝的配置比較簡單,無非是尋找安裝類,並執行安裝並獲取容器,所有的安裝類都需要繼承自IWindsorInstaller,此接口規定了方法如下:
void Install(IWindsorContainer container, IConfigurationStore store)此方法用於執行容器里具體類的注冊,類注冊將在下面學習。首先看看安裝的配置:
WindsorContainer _container = new WindsorContainer(); _container.Install( FromAssembly.This(), //FromAssembly.Named("CastleWindsor"), //FromAssembly.Containing<ServicesInstaller>(), //FromAssembly.InDirectory(new AssemblyFilter("Extensions")), //FromAssembly.Instance(this.GetPluginAssembly()) );
以上用install方法的每一個參數對應的配置均會被加載,如果即傳入了FromAssembly.This()又傳入了 FromAssembly.Named("CastleWindsor"),那么程序集CastleWindsor里的實現類將會被重復注冊拋錯,所以得小心不能重復注冊相同的實現類。
實現類的配置
實現類的配置多種多樣,根據實際需求可組合出不同的配置方式,以下就學習下一些常見的配置,高級配置可自行參考官方文檔http://docs.castleproject.org/Windsor.Fluent-Registration-API-Extensions.ashx
要想配置實現類到容易必須新建一個安裝類並在安裝類的install方法下配置,如下:
<pre name="code" class="csharp"> public class ChargeInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { //container.Register( // Component.For<IPrinter>().ImplementedBy<WenZhouPrinter>(), // Component.For<ICharge>().ImplementedBy<WenZhouCharge>()); //container.Register(Classes.FromThisAssembly().InNamespace("CastleWindsor.IEntity").WithService.DefaultInterfaces()); WenZhouPrinter wz = new WenZhouPrinter(); container.Register( Component.For<LoggingInterceptor>().LifeStyle.Transient, Component.For<IFactory>().ImplementedBy<PrintFactory>(), Component.For<IPrinter>().UsingFactoryMethod(p => p.Resolve<IFactory>().GetPrint()), Component.For<ICharge>().ImplementedBy<WenZhouCharge>() .DependsOn(Dependency.OnValue("twitterApiKey", "123")) ); //繼承兩個接口 // container.Register( // Component.For<IUserRepository, IRepository>() // .ImplementedBy<MyRepository>() //); //簡單工廠 //container // .Register( // Component.For<IMyService>() // .UsingFactoryMethod( // () => MyLegacyServiceFactory.CreateMyService()) // ); // 泛型配置 //container.Register( // Component.For(typeof(IRepository<>) // .ImplementedBy(typeof(NHRepository<>) //); //實體生命周期 //container.Register( // Component.For<IMyService>() // .ImplementedBy<MyServiceImpl>() // .LifeStyle.Transient //.Named("myservice.default") // ); //取先注冊的 //container.Register( // Component.For<IMyService>().ImplementedBy<MyServiceImpl>(), // Component.For<IMyService>().ImplementedBy<OtherServiceImpl>() //); //強制取后注冊的 //container.Register( // Component.For<IMyService>().ImplementedBy<MyServiceImpl>(), // Component.For<IMyService>().Named("OtherServiceImpl").ImplementedBy<OtherServiceImpl>().IsDefault() //); //注冊已經存在的 //var customer = new CustomerImpl(); //container.Register( // Component.For<ICustomer>().Instance(customer) // ); } }
配置中可以使用UsingFactoryMethod來將對應的接口的工廠方法注冊到容器中,容器可通過該工廠方法獲取實現類,以上分別有簡單工廠和工廠方法的配置。
通過DependsOn(Dependency.OnValue("twitterApiKey", "123")可向實現類的字段twitterApiKey注入”123“字符串值。
通過設置IsDefault來規定多個實現類的默認獲取過來的類。