[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的创建

posted @ 2016-03-07 16:46  Never、C  阅读(1660)  评论(5编辑  收藏  举报