我在MVC中使用Castle.Windsor是這樣用的。ide
首先在UI層安裝Install Castle.Windsor函數
在App_Start中增長一個類WindsorActivator,用於註冊和銷燬Containter。注意,這裏是在PreApplicationStartMethod中註冊的,是在ApplicationShutdownMethod中銷燬的。測試
using Castle.Windsor; using Castle.Windsor.Installer; using System; using WebActivatorEx; [assembly: PreApplicationStartMethod(typeof(TaskManagement.UI.App_Start.WindsorActivator), "PreStart")] [assembly: ApplicationShutdownMethodAttribute(typeof(TaskManagement.UI.App_Start.WindsorActivator), "Shutdown")] namespace TaskManagement.UI.App_Start { public static class WindsorActivator { public static IWindsorContainer Container; public static void PreStart() { //將這個Assembly中全部實現IWindsorInstaller接口的類都註冊 Container = new WindsorContainer().Install(FromAssembly.This()); } public static void Shutdown() { if (Container != null) Container.Dispose(); } } }
新建一個Installers文件夾,在該文件夾中分別添加多個Installer文件,用於註冊DA、Service、Infrastructure層的內容,舉例ServiceInstaller.cs文件:ui
using System; using System.Collections.Generic; using System.Linq; using System.Web; using Castle.MicroKernel.Registration; using Castle.MicroKernel.SubSystems.Configuration; using Castle.Windsor; using TaskManagement.Service.Implementation; namespace TaskManagement.UI.Installers { public class ServiceInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { //container.Register(Classes.FromThisAssembly() // .IncludeNonPublicTypes() // .BasedOn<ITransient>() // .WithService.DefaultInterfaces() // .LifestyleTransient()); container.Register(Classes.FromAssemblyNamed("TaskManagement.Service") //.IncludeNonPublicTypes() .BasedOn<BaseService>() .WithService .DefaultInterfaces() //使用默認的I+ServiceName的方式來取Service .LifestylePerWebRequest()); //.LifestyleTransient()); } } }
其中ControllerInstaller比較特殊:this
using System.Web.Mvc; using Castle.MicroKernel.Registration; using Castle.MicroKernel.SubSystems.Configuration; using Castle.Windsor; namespace TaskManagement.UI.Installers { using Plumbing; public class ControllersInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { //container.Register( // Classes. // FromThisAssembly(). // BasedOn<IController>(). // If(c => c.Name.EndsWith("Controller")). // LifestyleTransient()); //ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container)); container.Register(Classes.FromThisAssembly(). BasedOn<IController>(). If(c => c.Name.EndsWith("Controller")) .LifestyleTransient()); container.Register(Classes.FromThisAssembly() .BasedOn<Controller>() .LifestyleTransient() ); //設置指定的Controller的工廠,以替代系統默認的工廠 ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container)); } } }
須要額外的一個工廠類來取代默認的DefaultControllerFactory:spa
using System; using System.Web; using System.Web.Mvc; using System.Web.Routing; using Castle.Windsor; namespace TaskManagement.UI.Plumbing { public class WindsorControllerFactory : DefaultControllerFactory { readonly IWindsorContainer container; public WindsorControllerFactory(IWindsorContainer container) { this.container = container; } protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) { if (controllerType != null && container.Kernel.HasComponent(controllerType)) return (IController)container.Resolve(controllerType); return base.GetControllerInstance(requestContext, controllerType); } public override void ReleaseController(IController controller) { container.Release(controller); } } }
使用:code
一、屬性註冊blog
public class RoleS : BaseService, IRoleS { public IRoleR _IRoleR { get; set; } public IViewR _IViewR { get; set; } public IViewActionR _IViewActionR { get; set; }
直接使用便可,注意接口要申明爲Public的。接口
二、構造函數註冊。可能在測試、外部調用、Windows服務等狀況下用到。get
public class ChangeLogS : BaseService, IChangeLogS { public IChangeLogR _IChangeLogR { get; set; } public ChangeLogS(IChangeLogR iChangeLogR) { _IChangeLogR = iChangeLogR; }
三、UI層的Help 類中使用
var _IDepartmentR = WindsorActivator.Container.Kernel.Resolve<IDepartmentR>();