zoukankan      html  css  js  c++  java
  • Unity注入

    【此文引用别人,作为随笔自己看。】今天写《WCF技术剖析(卷2)》关于《WCF扩展》一章,举了“如何通过WCF扩展实现与IoC框架(以Unity为例)集成”(《通过自定义ServiceHost实现对WCF的扩展[实例篇]》)的例子。为了展示Unity如何实现几种典型的注入方式(构造器注入、属性注入和方法注入),我写了一个简单的小程序。如果读者对Unity或者IoC没有太多概念,我觉得这个小程序对于你初步地认识它们具有一定的帮助意义。如果你对Unity或者IoC有深入的认识,请忽略本文。[源代码从这里下载]

    首先创建一个控制台程序,并添加如下两个基于Unity的程序集被引用:Microsoft.Practices.Unity.dll和Microsoft.Practices.Unity.Configuration.dll。然后定义如下几个接口(IA、IB、IC和ID)和它们各自的实现类(A、B、C、D)。在类型A中定义了3个属性B、C和D,其类型分别为接口IB、IC和ID。其中属性B在构在函数中被初始化;属性C上应用了Microsoft.Practices.Unity.DependencyAttribute特性,意味着这是一个需要以属性注入方式被初始化的依赖属性;属性D则通过方法Initialize初始化,该方法上应用了Microsoft.Practices.Unity.InjectionMethodAttribute,意味着这是一个注入方法会被自动调用。

       1: namespace UnityDemo
       2: {
       3:     public interface IA { }
       4:     public interface IB { }
       5:     public interface IC { }
       6:     public interface ID {}
       7:  
       8:     public class A : IA
       9:     {
      10:         public IB B { get; set; }
      11:         [Dependency]
      12:         public IC C { get; set; }
      13:         public ID D { get; set; }
      14:  
      15:         public A(IB b)
      16:         {
      17:             this.B = b;
      18:         }
      19:         [InjectionMethod]
      20:         public void Initialize(ID d)
      21:         {
      22:             this.D = d;
      23:         }
      24:     }
      25:     public class B: IB{}
      26:     public class C: IC{}
      27:     public class D: ID{}
      28: }

    然后我们为该应用添加一个配置文件,并定义如下一段关于Unity的配置。在这段配置中,定义了一个名称为defaultContainer的Unity容器,并在其中完成了上面定义的接口和对应实现类之间映射的类型匹配。

      1: <?xml version="1.0"?>
       2: <configuration>
       3:   <configSections>
       4:     <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
       5:   </configSections>
       6:   <unity>
       7:     <containers>
       8:       <container name="defaultContainer">
       9:         <register type="UnityDemo.IA, UnityDemo" mapTo="UnityDemo.A, UnityDemo"/>
      10:         <register type="UnityDemo.IB, UnityDemo" mapTo="UnityDemo.B, UnityDemo"/>
      11:         <register type="UnityDemo.IC, UnityDemo" mapTo="UnityDemo.C, UnityDemo"/>
      12:         <register type="UnityDemo.ID, UnityDemo" mapTo="UnityDemo.D, UnityDemo"/>
      13:       </container>
      14:     </containers>
      15:   </unity> 
      16: </configuration>

    最后在Main方法中编写如下的程序:创建一个代表IoC容器的UnityContainer对象,并加载配置信息对其进行初始化。然后调用它的泛型的Resolve方法创建一个实现了泛型接口IA的对象。最后将返回对象转变成类型A,并检验其B、C和D属性是否是空。

     1: static void Main(string[] args)
       2: {
       3:     IUnityContainer container = new UnityContainer();
       4:     UnityConfigurationSection configuration = (UnityConfigurationSection)ConfigurationManager.GetSection(UnityConfigurationSection.SectionName);
       5:     configuration.Configure(container, "defaultContainer");
       6:     A a = container.Resolve<IA>() as A;
       7:     if (null != a)
       8:     {
       9:         Console.WriteLine("a.B == null ? {0}", a.B == null ? "Yes" : "No");
      10:         Console.WriteLine("a.C == null ? {0}", a.C == null ? "Yes" : "No");
      11:         Console.WriteLine("a.D == null ? {0}", a.D == null ? "Yes" : "No");
      12:     }
      13: }

    从如下给出的执行结果我们可以得到这样的结论:通过Resolve<IA>方法返回的是一个类型为A的对象;该对象的三个属性被进行了有效的初始化。这个简单的程序分别体现了接口注入(通过相应的接口根据配置解析出相应的实现类型)、构造器注入(属性B)、属性注入(属性C)和方法注入(属性D)。

       1: a.B == null ? No
       2: a.C == null ? No
       3: a.D == null ? No

    关于IoC/DI

    所谓控制反转(IoC: Inversion Of Control)就是应用本身不负责依赖对象的创建和维护,而交给一个外部容器来负责。这样控制权就由应用转移到了外部IoC容器,控制权就实现了所谓的反转。比如,在类型A中需要使用类型B的实例,而B实例的创建并不由A来负责,而是通过外部容器来创建。

    有时我们又将IoC成为依赖注入(DI: Dependency Injection)。所谓依赖注入,就是由外部容器在运行时动态地将依赖的对象注入到组件之中。具体的依赖注入方式又包括如下三种典型的形式。

    • 构造器注入(Constructor Injection):IoC容器会智能地选择选择和调用适合的构造函数以创建依赖的对象。如果被选择的构造函数具有相应的参数,IoC容器在调用构造函数之前会自定义创建相应参数对象;
    • 属性注入(Property Injection):如果需要使用到被依赖对象的某个属性,在被依赖对象被创建之后,IoC容器会自动初始化该属性;
    •  方法注入(Method Injection):如果被依赖对象需要调用某个方法进行相应的初始化,在该对象创建之后,IoC容器会自动调用该方法。

    在开源社区,具有很有流行的IoC框架,比如Castle Windsor、Unity、Spring.NET、StructureMap、Ninject等。

  • 相关阅读:
    无法重用Linq2Entity Query
    The Joel Test
    MSBuilder directly instead of default VSComplie with keyborad shotcut 原创
    客户端缓存(Client Cache)
    关于代码重构和UT的一些想法,求砖头
    ExtJS2.0实用简明教程 应用ExtJS
    Perl information,doc,module document and FAQ.
    使用 ConTest 进行多线程单元测试 为什么并行测试很困难以及如何使用 ConTest 辅助测试
    史上最简单的Hibernate入门简介
    汽车常识全面介绍 传动系统
  • 原文地址:https://www.cnblogs.com/NotEnough/p/7515309.html
Copyright © 2011-2022 走看看