zoukankan      html  css  js  c++  java
  • [Solution] DI原理解析及Castle、Unity框架使用

    本节目录

    DI介绍

    控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题.

    依赖注入(Dependency Injection,英文缩写为DI)是一种设计模式.

    其实本质都是指同一件事,强调的内容不一样.IoC强调容器的作用,DI强调注入的作用.

    通常IoC和DI可以理解为一个意思,只是指的对象不同.

    DI基本原理

    DI本质上是通过容器来反射创建实例.

    1个简单的类

        class Person
        {
            public void Say()
            {
                Console.WriteLine("Person's say method is Called");
            }
        }
    

     反射代码(className:类的全限定名)

            private static object CreateInstance(Assembly assembly, string className)
            {
                var type = assembly.GetType(className);
                return type != null ? Activator.CreateInstance(type) : null;
            }
    

    执行(XX为命名空间)

            static void Main(string[] args)
            {
                var obj = CreateInstance(Assembly.GetExecutingAssembly(), "XX.Person");
                var person = obj as Person;
                if (person != null)
                {
                    person.Say();
                }
                Console.ReadKey();
            }
    

    在上面能看到1个问题,一般情况下.既然使用DI,就不知道具体的注入对象.所以强调面向接口编程.

    所以实际上一般先定义接口,再通过DI容器创建对象.

        interface IPerson
        {
            void Say();
        }
        class Person : IPerson
        {
            public void Say()
            {
                Console.WriteLine("Person's say method is Called");
            }
        }
    

    执行

            static void Main(string[] args)
            {
                var obj = CreateInstance(Assembly.GetExecutingAssembly(), "Demo.Person");
                var person = obj as IPerson;
                if (person != null)
                {
                    person.Say();
                }
                Console.ReadKey();
            }
    

    DI框架

    DI框架流行的有Castle Windsor,Unity...(Autofac Spring.Net已经聊过,不再演示)

    在DI框架中,一般需要将对象注册到容器中,然后从容器解析出来.

     

    Castle

    Install-Package Castle.Windsor

    待注入类

      interface ITransient
        {
             
        }
    
        interface IPerson
        {
            void Say();
        }
        class Person : IPerson, ITransient
        {
            public void Say()
            {
                Console.WriteLine("Person's say method is Called");
            }
        }
    

    注册解析方式一

            static void Main(string[] args)
            {
                using (var container = new WindsorContainer())
                {
                    container.Register(Component.For<Person, IPerson>());
                    var person = container.Resolve<IPerson>();
                    person.Say();
                }
                Console.ReadKey();
            }
    

    注册解析方式二

        public class AssmInstaller : IWindsorInstaller
        {
            public void Install(IWindsorContainer container, IConfigurationStore store)
            {
                container.Register(Classes.FromThisAssembly()   //选择Assembly
                    .IncludeNonPublicTypes()                    //约束Type
                    .BasedOn<ITransient>()                         //约束Type
                    .WithService.DefaultInterfaces()            //匹配类型
                    .LifestyleTransient());                     //注册生命周期
            }
        }
    
            static void Main(string[] args)
            {
                using (var container = new WindsorContainer())
                {
                    container.Install(new AssmInstaller());
                    var person = container.Resolve<IPerson>();
                    person.Say();
                }
                Console.ReadKey();
            }

    构造函数注入

        class Task : ITransient
        {
            public IPerson Person { get; set; }
            public Task(IPerson person)
            {
                Person = person;
                Person.Say();
            }
        }
    
            static void Main(string[] args)
            {
                using (var container = new WindsorContainer())
                {
                    container.Install(new AssmInstaller());
                    container.Resolve<Task>();
                }
                Console.ReadKey();
            }

    属性注入

        class Task : ITransient
        {
            public IPerson Person { get; set; }
            public Task()
            {
            }
            public void Say()
            {
                Person.Say();
            }
        }
    
            static void Main(string[] args)
            {
                using (var container = new WindsorContainer())
                {
                    container.Install(new AssmInstaller());
                    container.Resolve<Task>().Say();
                }
                Console.ReadKey();
            }
    

    MVC集成

    Install-Package Castle.Windsor.Mvc

    Application_Start注册

            protected void Application_Start()
            {
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                var container = new WindsorContainer()
                    .Install(FromAssembly.This());
                var controllerFactory = new WindsorControllerFactory(container.Kernel);
                ControllerBuilder.Current.SetControllerFactory(controllerFactory);
            }
    

    Installer注册

        public class AssmInstaller : IWindsorInstaller
        {
            public void Install(IWindsorContainer container, IConfigurationStore store)
            {
                container.Register(Classes.FromThisAssembly()
                    .IncludeNonPublicTypes()
                    .BasedOn<ITransient>()
                    .WithService.DefaultInterfaces()
                    .LifestyleTransient());
                container.Register(Classes.FromThisAssembly()
                    .BasedOn<Controller>()
                    .LifestyleTransient()
                    );
            }
        }

    这样Castle Windsor就能接管解析Controller了.

    Unity

    Install-Package Unity

    待注入类

        public interface IPerson
        {
            void Say();
        }
        public class Person : IPerson
        {
            public void Say()
            {
                Console.WriteLine("Person's say method is Called");
            }
        }
    

    注册解析一

            static void Main(string[] args)
            {
                using (var container = new UnityContainer())
                {
                    container.RegisterType<IPerson, Person>(new TransientLifetimeManager());
                    var person = container.Resolve<IPerson>();
                    person.Say();
                }
                Console.ReadKey();
            }
    

    注册解析二

            static void Main(string[] args)
            {
                using (var container = new UnityContainer())
                {
                    container.RegisterInstance<IPerson>(new Person());
                    var person = container.Resolve<IPerson>();
                    person.Say();
                }
                Console.ReadKey();
            }
    

    构造函数注入

        class Task : ITask
        {
            public IPerson Person { get; set; }
            public Task(IPerson person)
            {
                Person = person;
                Person.Say();
            }
        }
    
        public interface ITask
        {
    
        }
    
            static void Main(string[] args)
            {
                using (var container = new UnityContainer())
                {
                    container.RegisterInstance<IPerson>(new Person());
                    container.RegisterType<ITask, Task>();
                    container.Resolve<ITask>();
                }
                Console.ReadKey();
            }

    属性注入

        class Task : ITask
        {
            [Dependency]
            public IPerson Person { get; set; }
            public Task(IPerson person)
            {
                Person = person;
            }
            public void Say()
            {
                Person.Say();
            }
        }
    
            static void Main(string[] args)
            {
                using (var container = new UnityContainer())
                {
                    container.RegisterInstance<IPerson>(new Person());
                    container.RegisterType<ITask, Task>();
                    var task = container.Resolve<ITask>();
                    task.Say();
                }
                Console.ReadKey();
            }

    MVC集成

    Install-Package Unity.Mvc

    Application_Start注册

            protected void Application_Start()
            {
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                var container = new UnityContainer();
                container.RegisterType<IPerson, Person>();
                DependencyResolver.SetResolver(new UnityDependencyResolver(container));
            }
    

    这样Unity就接管了Controller的创建

  • 相关阅读:
    图片的存储
    【已解决】如图,说我磁盘不够,看到var目录下有的个隐藏文件夹占了46G,不知道怎么删除
    Java 中时间处理SimpleDateFormat 中HH和hh的区别
    api的日志
    网页报警提示 This page includes a password or credit card input in a non-secure context. A warning has been added to the URL bar. For more information, see https://goo.gl/zmWq3m.
    Springboot项目中的favicon
    页面Header自适应屏幕
    Vue 日期下拉框
    VUE 单选下拉框Select中动态加载 默认选中第一个
    Vue 循环 [Vue warn]: Avoid using non-primitive value as key
  • 原文地址:https://www.cnblogs.com/neverc/p/5242448.html
Copyright © 2011-2022 走看看