MVC中使用Castle.Windsor

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

 

新建一個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());
        }
    }
}
View Code

 

其中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);
        }
    }
}
DefaultControllerFactory

 

使用: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>();
相關文章
相關標籤/搜索