翻譯
當使用依賴注入容器時,你首先要向容器中注冊你的組件,Windsor使用installers(該類型實現IWindsorInstaller接口)來封裝和隔離注冊的邏輯,可以使用Configuration和FromAssembly來完成工作。
Installers是實現了IWindsorInstaller接口的簡單類型,只有一個Install方法,該方法接收container參數,該參數使用 fluent registration API方式來注冊組件
public class RepositoriesInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register(AllTypes.FromAssemblyNamed("Acme.Crm.Data") .Where(type => type.Name.EndsWith("Repository")) .WithService.DefaultInterfaces() .Configure(c => c.LifeStyle.PerWebRequest)); } }
備注:使用單獨的installer來注冊一些相關的服務信息(如repositories、controllers)
installer必須是公共的而且包含一個公共的默認構造函數,Windsor使用InstallerFactory掃描公開的installers
使用installers
var container = new WindsorContainer(); container.Install( new ControllersInstaller(), new RepositoriesInstaller(), // and all your other installers );
當有新的intallers,要記得在這里注冊
如果installers過多,添加這些代碼有點乏味。Windsor提供FromAssembly靜態類和Configuration來進行外部的配置
FromAssembly靜態類會掃描指定的程序集中所有實現IWindsorInstaller接口的類,如果添加新的installer,則不用添加額外代碼,Windsor會自動檢測到類型並實例化
container.Install( FromAssembly.This(), FromAssembly.Named("Acme.Crm.Bootstrap"), FromAssembly.Containing<ServicesInstaller>(), FromAssembly.InDirectory(new AssemblyFilter("Extensions")), FromAssembly.Instance(this.GetPluginAssembly()) );
installer的注冊沒有特定的順序,所以你不知道哪個installer先被注冊,如果要進行特殊的排序,使用InstallerFactory來實現
public class WindsorBootstrap : InstallerFactory { public override IEnumerable<Type> Select(IEnumerable<Type> installerTypes) { var retval = installerTypes.OrderBy(x => this.GetPriority(x)); return retval; } private int GetPriority(Type type) { var attribute = type.GetCustomAttributes(typeof(InstallerPriorityAttribute), false).FirstOrDefault() as InstallerPriorityAttribute; return attribute != null ? attribute.Priority : InstallerPriorityAttribute.DefaultPriority; } } [AttributeUsage(AttributeTargets.Class)] public sealed class InstallerPriorityAttribute : Attribute { public const int DefaultPriority = 100; public int Priority { get; private set; } public InstallerPriorityAttribute(int priority) { this.Priority = priority; } } container.Install(FromAssembly.This(new WindsorBootstrap()));
給installer添加特性進行排序
1. FromAssembly.This() 調用該方法的程序集
2. FromAssembly.Named("Acme.Crm.Bootstrap")
Install from assembly with specified assembly name using standard .NET assembly locating mechanism.
You can also provide path to a .dll or .exe file when you have the assembly in some non-standard location.
如果是.dll,要使用絕對路徑
3. FromAssembly.Containing
程序集中包含特定的類型
Configuration 類
讀取xml文件的配置信息
container.Install( Configuration.FromAppConfig(), Configuration.FromXmlFile("settings.xml"), Configuration.FromXml(new AssemblyResource("assembly://Acme.Crm.Data/Configuration/services.xml")) );
settings.xml文件格式如下
<?xml version="1.0" encoding="utf-8" ?> <configuration> <installers> <install type="WindsorInstaller.CustomerInstaller,WindsorInstaller"/> <install type="WindsorInstaller.SecondInstaller,WindsorInstaller"/> </installers> </configuration>
Windsor自動獲取xml文件中的installers
也可以寫在應用程序配置文件中
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" /> </configSections> <castle> <installers> <install type="WindsorInstaller.CustomerInstaller,WindsorInstaller"/> <install type="WindsorInstaller.SecondInstaller,WindsorInstaller"/> <!--查找該程序集下所有IWindsorInstaller接口的類型進行注冊--> <!--<install assembly="WindsorInstaller"></install>--> <!--查找dll文件--> <!--<install directory="Extensions" fileMask="*.dll"></install>--> </installers> </castle> </configuration>