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个简单的类

    1

    2

    3

    4

    5

    6

    7

    class Person

    {

        public void Say()

        {

            Console.WriteLine("Person's say method is Called");

        }

    }

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

    1

    2

    3

    4

    5

    private static object CreateInstance(Assembly assembly, string className)

    {

        var type = assembly.GetType(className);

        return type != null ? Activator.CreateInstance(type) : null;

    }

    执行(XX为命名空间)

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    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容器创建对象.

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    interface IPerson

    {

        void Say();

    }

    class Person : IPerson

    {

        public void Say()

        {

            Console.WriteLine("Person's say method is Called");

        }

    }

    执行

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    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

    待注入类

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    interface ITransient

      {

            

      }

      interface IPerson

      {

          void Say();

      }

      class Person : IPerson, ITransient

      {

          public void Say()

          {

              Console.WriteLine("Person's say method is Called");

          }

      }

    注册解析方式一

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

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

    }

    注册解析方式二

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    public class AssmInstaller : IWindsorInstaller

    {

        public void Install(IWindsorContainer container, IConfigurationStore store)

        {

            container.Register(Classes.FromThisAssembly()  //选择Assembly

                .IncludeNonPublicTypes()                   //约束Type

                .BasedOn<ITransient>()                         //约束Type

                .WithService.DefaultInterfaces()           //匹配类型

                .LifestyleTransient());                    //注册生命周期

        }

    }

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    static void Main(string[] args)

    {

        using (var container = new WindsorContainer())

        {

            container.Install(new AssmInstaller());

            var person = container.Resolve<IPerson>();

            person.Say();

        }

        Console.ReadKey();

    }

    构造函数注入

    1

    2

    3

    4

    5

    6

    7

    8

    9

    class Task : ITransient

    {

        public IPerson Person { getset; }

        public Task(IPerson person)

        {

            Person = person;

            Person.Say();

        }

    }

    1

    2

    3

    4

    5

    6

    7

    8

    9

    static void Main(string[] args)

    {

        using (var container = new WindsorContainer())

        {

            container.Install(new AssmInstaller());

            container.Resolve<Task>();

        }

        Console.ReadKey();

    }

    属性注入

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    class Task : ITransient

    {

        public IPerson Person { getset; }

        public Task()

        {

        }

        public void Say()

        {

            Person.Say();

        }

    }

    1

    2

    3

    4

    5

    6

    7

    8

    9

    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注册

    1

    2

    3

    4

    5

    6

    7

    8

    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注册

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    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

    待注入类

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    public interface IPerson

    {

        void Say();

    }

    public class Person : IPerson

    {

        public void Say()

        {

            Console.WriteLine("Person's say method is Called");

        }

    }

    注册解析一

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

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

    }

    注册解析二

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    static void Main(string[] args)

    {

        using (var container = new UnityContainer())

        {

            container.RegisterInstance<IPerson>(new Person());

            var person = container.Resolve<IPerson>();

            person.Say();

        }

        Console.ReadKey();

    }

    构造函数注入

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    class Task : ITask

    {

        public IPerson Person { getset; }

        public Task(IPerson person)

        {

            Person = person;

            Person.Say();

        }

    }

    public interface ITask

    {

    }

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    static void Main(string[] args)

    {

        using (var container = new UnityContainer())

        {

            container.RegisterInstance<IPerson>(new Person());

            container.RegisterType<ITask, Task>();

            container.Resolve<ITask>();

        }

        Console.ReadKey();

    }

    属性注入

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    class Task : ITask

    {

        [Dependency]

        public IPerson Person { getset; }

        public Task(IPerson person)

        {

            Person = person;

        }

        public void Say()

        {

            Person.Say();

        }

    }

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    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注册

    1

    2

    3

    4

    5

    6

    7

    protected void Application_Start()

    {

        RouteConfig.RegisterRoutes(RouteTable.Routes);

        var container = new UnityContainer();

        container.RegisterType<IPerson, Person>();

        DependencyResolver.SetResolver(new UnityDependencyResolver(container));

    }

    这样Unity就接管了Controller的创建

     
  • 相关阅读:
    mybatis批量插入数据
    oracle的dmp数据文件的导出和导入以及创建用户
    maven安装第三方jar包到本地仓库
    IntelliJ IDEA 注册码,激活
    分布式事务实现-Spanner
    Redis Cluster原理
    twemproxy源码分析
    Paxos可容错的一致性协议
    UpdateServer事务实现机制
    Coroutine及其实现
  • 原文地址:https://www.cnblogs.com/zhaodahai/p/6824072.html
Copyright © 2011-2022 走看看