MVC中使用Castle.Windsor


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

 

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

 

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

 

使用:

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM