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

时间: 2024-08-10 02:09:44

[Solution] DI原理解析及Castle、Unity框架使用的相关文章

[Solution] AOP原理解析及Castle、Autofac、Unity框架使用

AOP介绍 面向切面编程(Aspect Oriented Programming,英文缩写为AOP),通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. AOP是OOP的延续,是软件开发中的一个热点. 常用于: Authentication Caching Lazy loading Transactions AOP基本原理 普通类 1 2 3 4 5 6 7 8 9 class Person : MarshalByRefObject {     public string Say(

MyBatis框架中Mapper映射配置的使用及原理解析(七) MapperProxy,MapperProxyFactory

从上文<MyBatis框架中Mapper映射配置的使用及原理解析(六) MapperRegistry> 中我们知道DefaultSqlSession的getMapper方法,最后是通过MapperRegistry对象获得Mapper实例: public <T> T getMapper(Class<T> type, SqlSession sqlSession) { final MapperProxyFactory<T> mapperProxyFactory =

MyBatis框架中Mapper映射配置的使用及原理解析(三) 配置篇 Configuration

从上文<MyBatis框架中Mapper映射配置的使用及原理解析(二) 配置篇 SqlSessionFactoryBuilder,XMLConfigBuilder> 我们知道XMLConfigBuilder调用parse()方法解析Mybatis配置文件,生成Configuration对象. Configuration类主要是用来存储对Mybatis的配置文件及mapper文件解析后的数据,Configuration对象会贯穿整个Mybatis的执行流程,为Mybatis的执行过程提供必要的配

MyBatis框架中Mapper映射配置的使用及原理解析(二) 配置篇 SqlSessionFactoryBuilder,XMLConfigBuilder

在 <MyBatis框架中Mapper映射配置的使用及原理解析(一) 配置与使用> 的demo中看到了SessionFactory的创建过程: SqlSessionFactory sessionFactory = null; String resource = "mybatisConfig.xml"; try { sessionFactory = new SqlSessionFactoryBuilder().build(Resources .getResourceAsRea

Android热修复框架AndFix原理解析及使用

一.前言 最近腾讯弄出一个Tinker热修复框架,那么本文先不介绍这个框架,先来介绍一下阿里的一个热修复框架AndFix,这个框架出来已经很长时间了,但是看网上没有太多非常详细的讲解,这里就来做一次分析.正好项目中要使用到.首先这个框架是开源的:https://github.com/alibaba/AndFix 其实在最早的时候我已经分析了阿里的另外一个热修复框架:Dexposed框架,还不了解的同学可以点击这里查看:Dexposed框架原理解析以及使用 当时介绍这个框架的时候发现他的实现原理很

ABP中动态WebAPI原理解析

ABP中动态WebAPI原理解析 动态WebAPI应该算是ABP中最Magic的功能之一了吧.开发人员无须定义继承自ApiController的类,只须重用Application Service中的类就可以对外提供WebAPI的功能,这应该算是对DRY的最佳诠释了. 如下图所示,一行代码就为所有实现了IApplicationService的类型,自动创建对应的动态WebAPI. 这么Magic的功能是如何实现的呢? 本文为你揭开其Magic的外表.你会发现,实现如此Magic的功能,最关键的代码

数据库水平切分的实现原理解析

数据库水平切分的实现原理解析---分库,分表,主从,集群,负载均衡器 随着互联网应用的广泛普及,海量数据的存储和访问成为了系统设计的瓶颈问题.对于一个大型的互联网应用,每天几十亿的PV无疑对数据库造成了相当高的负载.对于系统的稳定性和扩展性造成了极大的问题.通过数据切分来提高网站性能,横向扩展数据层已经成为架构研发人员首选的方式.水平切分数据库,可以降低单台机器的负载,同时最大限度的降低了了宕机造成的损失.通过负载均衡策略,有效的降低了单台机器的访问负载,降低了宕机的可能性:通过集群方案,解决了

Spring?IOC设计原理解析:本文乃学习整理参考而来

Spring IOC设计原理解析:本文乃学习整理参考而来 一. 什么是Ioc/DI? 二. Spring IOC体系结构 (1) BeanFactory (2) BeanDefinition 三. IoC容器的初始化 1. XmlBeanFactory(屌丝IOC)的整个流程 2. FileSystemXmlApplicationContext 的IOC容器流程 1.高富帅IOC解剖 2. 设置资源加载器和资源定位 3.AbstractApplicationContext的refresh函数载入

Spring Boot启动原理解析

Spring Boot启动原理解析http://www.cnblogs.com/moonandstar08/p/6550758.html 前言 前面几章我们见识了SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说,如果不大懂SpringBoot内部启动原理,以后难免会吃亏.所以这次博主就跟你们一起一步步揭开SpringBoot的神秘面纱,让它不在神秘. 正文 我们开发任何一个Spring Boot项目,都会用到如下的启动类 从上面代码可以看出,Annotation定义(@Sp