Windsor 依赖注入

Posted student-note

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Windsor 依赖注入相关的知识,希望对你有一定的参考价值。

Windsor 学习

1.安装nuget   Install-Package Castle.Windsor

 安装后会多这两个引用 技术图片

 

 2.hello world

    class Program
    {
        static void Main(string[] args)
        {
            // 应用开始...
            var container = new WindsorContainer();

           // 使用windstorinstallers从执行程序集添加和配置所有组件
            container.Install(FromAssembly.This());

            // 实例化依赖
            var king = container.Resolve<IKing>();
            king.RuleTheCastle();
            // clean up, application exits
            container.Release(king);
            container.Dispose();
            Console.Read();
        }
    }
    public class RepositoriesInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(Classes.FromThisAssembly()
                                .Where(Component.IsInSameNamespaceAs<King>())
                                .WithService.DefaultInterfaces()
                                .LifestyleTransient());
        }
    }

    public interface IKing
    {
        void RuleTheCastle();
    }
    public class King : IKing
    {
        public void RuleTheCastle()
        {
            Console.WriteLine("调用方法成功啦!!!-=-");
        }
    }

技术图片

 

 

2.手动注入

  

        /// <summary>
        /// 手动注入
        /// </summary>
        private static void HandlerInit()
        {
            var container = new WindsorContainer();
            container.Register(Component.For<CI1>());
            container.Register(Component.For<I1>().ImplementedBy<C1>());
            container.Register(Component.For<I2>().ImplementedBy<C2>());
            var ci1 = container.Resolve<CI1>();
            container.Release(ci1);
            container.Dispose();
        }
    public interface I1
    {
        void Show1();
    }

    public interface I2
    {
        void Show2();
    }

    public class C1 : I1
    {
        public void Show1()
        {
            Console.WriteLine("C1");
        }
    }
    public class C2 : I2
    {
        public void Show2()
        {
            Console.WriteLine("C2");
        }
    }

    public class CI1
    {
        public CI1(I1 i1, I2 i2)
        {
            i1.Show1();
            i2.Show2();
        }
    }

技术图片

  这里可以看到CI1 构造函数需要的接口都被注入进来.调用成功

4.在asp.net mvc 中使用

   

public class MvcApplication : System.Web.HttpApplication
    {
        private static WindsorContainer contariner;

        protected void Application_End()
        {
            contariner.Dispose();
        }
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            contariner = new WindsorContainer();
            contariner.Install(FromAssembly.This());
            ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(contariner.Kernel));
        }
    }
   
    public class CustomeWindsorInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(Classes.FromThisAssembly().BasedOn<IController>().LifestyleTransient());

            container.Register(Component.For<I1>().ImplementedBy<C1>().LifestyleTransient());
           // container.Register(Classes.FromThisAssembly().Where(Component.IsInSameNamespaceAs<C1>()).WithService.DefaultInterfaces().LifestyleTransient());
        }
    }
    public class WindsorControllerFactory : DefaultControllerFactory
    {
        private readonly IKernel kernel;

        public WindsorControllerFactory(IKernel kernel)
        {
            this.kernel = kernel;
        }

        public override void ReleaseController(IController controller)
        {
            kernel.ReleaseComponent(controller);
        }

        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            if (controllerType == null)
            {
                throw new HttpException(404, string.Format("The controller for path ‘{0}‘ could not be found.", requestContext.HttpContext.Request.Path));
            }
            return (IController)kernel.Resolve(controllerType);
        }

    }

 5 高级用法

  1.注入泛型

  

        private static void SetGeneric()
        {
            var container = new WindsorContainer();
            container.Register(
                Component.For(typeof(IRespority<>))
                    .ImplementedBy(typeof(BaseRespority<>))
            );
            var rp = container.Resolve<IRespority<String>>();
            container.Release(rp);
            container.Dispose();
        }

   2.设置默认Component

 private static void Repeat() {
            var container = new WindsorContainer();
            container.Register(
                Component.For<r1>().ImplementedBy<cr1>(),//默认为第一个所以一直是cr1
                Component.For<r1>().ImplementedBy<cr2>()//.IsDefault() 可通过加上默认来指定
            );
            var rp = container.Resolve<r1>();
            container.Release(rp);
            container.Dispose();

        }

 3.指定依赖. 当一个类依赖的是接口,但是接口的实例有多个,可用这个处理

  

        /// <summary>
        /// 指定依赖
        /// </summary>
        private static void SetDepden() {

            var container = new WindsorContainer();
            container.Register(
                Component.For<r1>().ImplementedBy<cr1>().Named("r1.c1"),//默认为第一个所以一直是cr1
                Component.For<r1>().ImplementedBy<cr2>().Named("r1.c2")//.IsDefault() 可通过加上默认来指定
                ,Component.For<cc>().DependsOn(ServiceOverride.ForKey("r").Eq("r1.c2"))
            );
            var rp = container.Resolve<cc>();
            container.Release(rp);
            container.Dispose();
        }

4. 类多继承接口

            var container = new WindsorContainer();
            container.Register(
                Component.For<r1, r2>().ImplementedBy<cr1>().Named("r1.c1"),
                Component.For<r1>().ImplementedBy<cr2>().Named("r1.c2").IsDefault()
                , Component.For<cc>().DependsOn(ServiceOverride.ForKey("r").Eq("r1.c2"))
            );
            //接口继承于接口
            container.Register(
                Component.For<r1, r2>().Forward<r3>().ImplementedBy<cr1>()
                );
            var rp = container.Resolve<r1>();
            container.Release(rp);
            container.Dispose();

 

以上是关于Windsor 依赖注入的主要内容,如果未能解决你的问题,请参考以下文章

依赖注入 Castle.Windsor高级应用

Windsor 依赖注入

如何注入在 Windsor 注册的 MEF [ImportingConstructor] 依赖项?

Castle Windsor 实现依赖注入和APO

使用 Castle Windsor 进行 WCF 依赖注入 - 请帮忙?

使用 Castle Windsor 注入依赖项