我在MVC中使用Castle.Windsor是這樣用的。
首先在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文件:

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比較特殊:
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:

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); } } }
使用:
1、屬性注冊
public class RoleS : BaseService, IRoleS { public IRoleR _IRoleR { get; set; } public IViewR _IViewR { get; set; } public IViewActionR _IViewActionR { get; set; }
直接使用即可,注意接口要申明為Public的。
2、構造函數注冊。可能在測試、外部調用、Windows服務等情況下用到。
public class ChangeLogS : BaseService, IChangeLogS { public IChangeLogR _IChangeLogR { get; set; } public ChangeLogS(IChangeLogR iChangeLogR) { _IChangeLogR = iChangeLogR; }
3、UI層的Help 類中使用
var _IDepartmentR = WindsorActivator.Container.Kernel.Resolve<IDepartmentR>();