我在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>();