【此文引用别人,作为随笔自己看。】今天写《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,意味着这是一个注入方法会被自动调用。

   : namespace UnityDemo
: {
: public interface IA { }
: public interface IB { }
: public interface IC { }
: public interface ID {}
:
: public class A : IA
: {
: public IB B { get; set; }
: [Dependency]
: public IC C { get; set; }
: public ID D { get; set; }
:
: public A(IB b)
: {
: this.B = b;
: }
: [InjectionMethod]
: public void Initialize(ID d)
: {
: this.D = d;
: }
: }
: public class B: IB{}
: public class C: IC{}
: public class D: ID{}
: }

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

  : <?xml version="1.0"?>
: <configuration>
: <configSections>
: <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
: </configSections>
: <unity>
: <containers>
: <container name="defaultContainer">
: <register type="UnityDemo.IA, UnityDemo" mapTo="UnityDemo.A, UnityDemo"/>
: <register type="UnityDemo.IB, UnityDemo" mapTo="UnityDemo.B, UnityDemo"/>
: <register type="UnityDemo.IC, UnityDemo" mapTo="UnityDemo.C, UnityDemo"/>
: <register type="UnityDemo.ID, UnityDemo" mapTo="UnityDemo.D, UnityDemo"/>
: </container>
: </containers>
: </unity>
: </configuration>

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

 : static void Main(string[] args)
: {
: IUnityContainer container = new UnityContainer();
: UnityConfigurationSection configuration = (UnityConfigurationSection)ConfigurationManager.GetSection(UnityConfigurationSection.SectionName);
: configuration.Configure(container, "defaultContainer");
: A a = container.Resolve<IA>() as A;
: if (null != a)
: {
: Console.WriteLine("a.B == null ? {0}", a.B == null ? "Yes" : "No");
: Console.WriteLine("a.C == null ? {0}", a.C == null ? "Yes" : "No");
: Console.WriteLine("a.D == null ? {0}", a.D == null ? "Yes" : "No");
: }
: }

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

   : a.B == null ? No
: a.C == null ? No
: 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等。

最新文章

  1. Ubuntu 14.4 配置
  2. HBase with MapReduce (MultiTable Read)
  3. 杭电1009-FatMouse&#39; Trade
  4. Makefile文件简单整理
  5. Jsonp 前后端交互操作
  6. 【转】Mac和iOS开发资源汇总—更新于2013-07-19
  7. eclipse安装CDT插件遇到的问题
  8. PL/SQL拼接和使用绑定变量
  9. php 使用操作符
  10. 随机跳转页面之使用VBA公共变量
  11. laravel whereDoesntHave
  12. win 10 在vs2017下对mpi的安装以及认识
  13. 双列集合Map
  14. BZOJ1767/Gym207383I CEOI2009 Harbingers 斜率优化、可持久化单调栈、二分
  15. Python基础-day03
  16. 正确的C++/C堆栈
  17. 解题:POI 2010 Beads
  18. CentOS6.X关闭防火墙
  19. Ubuntu系统升级内核方法
  20. PHP关于传众多参数还是传上下文对象的性能测试

热门文章

  1. java.sql.SQLException: Access denied for user &#39;Administrator&#39;@&#39;localhost&#39; (using password: YES)
  2. 「USACO15FEB」「LuoguP3121」审查(黄金)Censoring (Gold)(AC自动机
  3. 百度之星2017初赛A
  4. 【Lintcode】074.First Bad Version
  5. vijos:P1155集合位置(次短路)
  6. POJ-3617
  7. 【网络爬虫】【python】网络爬虫(五):scrapy爬虫初探——爬取网页及选择器
  8. Umbraco examine search media folder 中的pdf文件
  9. 安装完SAP后BASIS的配置流程
  10. JS控制GridView行选择