IoC控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则用来解决系统耦合问题。 控制反转还有一个名字叫做依赖注入(DI:Dependency Injection)。IoC中最基本的技术就是interface + reflection,“反射(Reflection)”编程。 。" IoC 容器的职责是对象的创建,核心是对象的生命周期管理(何时创建/怎么创建/何时销毁),就像一个大工厂,对象“托管”在里面。模式的源头都是 SOLID(面向对象的原则)。利用IOC 解耦的核心是:面向抽象,而非实现。即我们只需要关注某一个对象能做什么,怎么用;不需要关注它怎么来,更不需要我们来管理它。
1,Unity 
Unity是Enterprise Library 4.0开始加入的一个轻量级的、可扩展的依赖注入容器。
Unity模块包括了下面的特点  
•  提供了一个创建对象,以及依赖的对象的方法  
•  提供的RegisterType方法用来在容器中注册类型和映射,Resolve方法可以返回任何依赖对象的实例。  
•  提供控制反转IOC功能,通过预先配置注入类的对象来实现。你可以在构造函数中指明一个类或者接口(构造函数注入),或者是使用attribute的属性注入,和方法调用注入。 
•  支持容器继承,容器可以有子容器,支持对象从子容器传递到父容器中。  
•  可以从标准的配置文件中读取信息,例如xml文件  
•  在运行时可以配置和改变依赖关系。  
•  对类的定义没有任何要求。在类上不需要添加attribute(除非使用属性注入或者是方法调用注入),在类声明中没有任何限制。  
•  支持自定义容器,例如,你可以在方法中实现额外的对象构造,和容器功能,例如容器的缓存功能。

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

定义一个接口:

    public interface ILogger
{
void Write(string message);
}

实现接口用来扩展应用程序:


    public class FlatFileLogger : ILogger
{
public void Write(string message)
{
Console.WriteLine(String.Format("Message:{0}", message));
Console.WriteLine("Target:FlatFile");
}
}

主程序:

    class Program
{
static void Main(string[] args)
{
ILogger logger = GetLogger();
logger.Write("Test");
System.Console.ReadLine();
}
/// <summary>
/// 加载日志处理对象
/// </summary>
/// <returns></returns>
public static ILogger GetLogger()
{
//初始化一个容器
IUnityContainer container = new UnityContainer();
//获取unity配置
UnityConfigurationSection config = ConfigurationManager.GetSection("unity") as UnityConfigurationSection;
UnityConfigurationSection.CurrentSection.Configure(container);
//向容器中注册对象
ILogger defaultLogger = container.Resolve<ILogger>("Logger");
return defaultLogger;
}
}

扩展配置:

<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>
</configSections>
<unity>
<typeAliases>
<typeAlias alias="FlatFileLogger" type="IoCTest.Unity.FlatFileLogger, IoCTest.Unity" />
<typeAlias alias="ILogger" type="IoCTest.Unity.ILogger, IoCTest.Unity" />
</typeAliases>
<containers>
<container>
<types>
<type name="Logger" type="ILogger" mapTo="FlatFileLogger" />
</types>
</container>
</containers>
</unity>
</configuration>

2,Spring.NET 
Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序。它提供了很多方面的功能,比如依赖注入、面向方面编程(AOP)、数据访问抽象及ASP.NET扩展等等。 Spring.NET的IoC容器所解决的,正是如何在企业应用中将类、对象和服务组合成应用程序的问题。IoC容器将分散的组件组合成完整的应用程序。 。Spring.Core的基础是IObjectFactory接口,该接口用一个简单而优雅的方式实现了工厂模式,使我们可以无需自行编写singleton类型和众多的服务定位器,并允许将对象配置及其依赖关系与具体的程序逻辑解耦。该模块中的IApplicationContext接口是IObjectFactory的扩展,增加了诸多企业级功能,包括使用资源文件进行文本本地化、事件传播和资源装载等等。
定义一个接口:

实现接口:

    public class FileLogger : ILogger
{
public void Write(string message)
{
Console.WriteLine(String.Format("Message:{0}", message));
Console.WriteLine("Target:File");
}
}

主程序:

        static void Main(string[] args)
{
//初始化容器
IApplicationContext context = ContextRegistry.GetContext();
//获取容器中的对象
ILogger Logger = context.GetObject("Logger") as ILogger;
Logger.Write("Test");
Console.ReadLine();
}

系统配置:

<configuration>
<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
</sectionGroup>
</configSections> <spring>
<context>
<resource uri="config://spring/objects"/>
</context>
<objects xmlns="http://www.springframework.net">
<object id="Logger" type="IoCTest.Spring.FileLogger,IoCTest.Spring" >
</object>
</objects>
</spring>
</configuration>

3、MEF组合部件
MEF(Managed Extensibility Framework ) 已经内置在.NET Framework 4.0里面了,只需要添加引用System.ComponentModel.Composition即可。 是.NET平台下一个提供轻量级的、可扩展的、类似插件式的系统架构的、且无需配置的(Attribute Based)扩展性管理框架,让我们可以轻松的对应用程序进行扩展并且对已有的代码产生最小的影响,开发人员在开发过程中根据功能要求定义一些扩展点,之后扩展人员就可以使用这些扩展点与应用程序交互;同时MEF让应用程序与扩展程序之间不产生直接的依赖,这样也允许在多个具有同样的扩展需求之间共享扩展程序。虽然微软的人极力否认MEF是一个IoC/DI的工具,但事实是它的确可以实现Ioc/DI。
使用 MEF 编写的可扩展应用程序的扩展点都会声明一个可由扩展组件(Parts)填充的导入(Import),每个扩展组件都会声明一个导出(Export)。MEF提供一种通过“组合”隐式发现部件的方法,对应用程序进行扩展。 所谓导入(Import)即:在容器中指定“哪个对象需要Compose”,所谓导出(Export)即:指定“哪个类可以被用来Compose”
契约接口:

声明导出:

    /// <summary>
/// 哪个类可以被用来Compose,也就是说这个类是不是可以用来填充的实现类,所以Export标记的是类,而不是具体的某个对象。
/// </summary>
[Export("ILogger1", typeof(ILogger))]
public class FileLogger1 : ILogger
{
public void Write(string message)
{
Console.WriteLine(String.Format("Message:{0}", message));
Console.WriteLine("Target:File");
}
}

声明导入:

    class Ts
{
/// <summary>
/// 哪个对象需要Compose。也就是需要被实现类给填充,所以Import标记的是对象,一般该对象是接口,因为如果是具体类的话,那还需要Import吗?
/// </summary>
[Import("ILogger1")]
public ILogger Logger { get; set; } public Ts()
{
var catalog = new AggregateCatalog();
//把从Program所在程序集中发现的部件添加到目录中
//catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly));
//把从指定path发现的部件添加到目录中
catalog.Catalogs.Add(new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory));
var container = new CompositionContainer(catalog);
//通过调用容器的ComposeParts()方法可以把容器中的部件组合到一起。
container.ComposeParts(this);
}
}

主程序:

static void Main(string[] args) { Ts ts = new Ts(); ts.Logger.Write("Test"); System.Console.ReadLine(); }

相对于Spring.net这样的框架来说,MEF的优势就是首先它是.NET Framework内置的,你无需添加第三方的引用,担心第三方组件的更新等问题;其次它是免配置的,对Spring.net这样的庞然大物来说免配置很有诱惑力。对Unity来说,它的优势是一样的,.NET Framework内置,无需配置,无需hard code的声明。当然更无需直接引用了,这是所有IoC都做到的。
MEF还可以通过metadata自动发现Parts而无需获取parts的assembly/dll。有关MEF的完整的介绍,请移步MSDN:http://msdn.microsoft.com/en-us/library/dd460648.aspx

.Net下实现可扩展的编程方法简述的更多相关文章

  1. Windows下使用NIF扩展Erlang方法

    在Erlang中,NIF(Native Implemented Function)被用来扩展erlang的某些功能,一般用来实现一些erlang很难实现的,或者一些erlang实现效率不高的功能. N ...

  2. ASP.NET MVC下的四种验证编程方式

    ASP.NET MVC采用Model绑定为目标Action生成了相应的参数列表,但是在真正执行目标Action方法之前,还需要对绑定的参数实施验证以确保其有效性,我们将针对参数的验证成为Model绑定 ...

  3. ASP.NET MVC下的四种验证编程方式【转】

    ASP.NET MVC采用Model绑定为目标Action生成了相应的参数列表,但是在真正执行目标Action方法之前,还需要对绑定的参数实施验证以确保其有效 性,我们将针对参数的验证成为Model绑 ...

  4. iOS利用block实现链式编程方法(Objective-C链式编程)

    objc利用block实现链式编程方法 因为不好读.block和其他语言的匿名函数一样,很多程序员刚开始很难主动去用他. 本文描述block作为属性的实际使用,看懂block,并讲解如何利用block ...

  5. Linux下搭建iSCSI共享存储的方法 Linux-IO Target 方式CentOS7-1810下实现

    iSCSI(internet SCSI)技术由IBM公司研究开发,是一个供硬件设备使用的.可以在IP协议的上层运行的SCSI指令集,这种指令集合可以实现在IP网络上运行SCSI协议,使其能够在诸如高速 ...

  6. Linux下搭建iSCSI共享存储的方法 Linux-IO Target 方式 Debian9.5下实现

    iSCSI(internet SCSI)技术由IBM公司研究开发,是一个供硬件设备使用的.可以在IP协议的上层运行的SCSI指令集,这种指令集合可以实现在IP网络上运行SCSI协议,使其能够在诸如高速 ...

  7. ASP.NET MVC下的四种验证编程方式[续篇]

    在<ASP.NET MVC下的四种验证编程方式>一文中我们介绍了ASP.NET MVC支持的四种服务端验证的编程方式("手工验证"."标注Validation ...

  8. paip.函数式编程方法概述以及总结

    paip.函数式编程方法概述以及总结 1     函数式编程:函数式风格..很多命令式语言里支持函数式编程风格 1.1      起源 (图灵机,Lisp机器, 神经网络计算机) 1.2      函 ...

  9. windows下制作PHP扩展

    一.编译PHP 转自:http://demon.tw/software/compile-php-on-windows.html 编译PHP扩展必需的一些头文件需要从php源码中获取,其中有一些配置性的 ...

随机推荐

  1. vimrc配置文件_version1.0_+pathogen, taglist, wordcomplete插件说明

    为了表示对Ruchee的感谢,首先这是Ruchee的个人网站:http://www.ruchee.com/index.html,他的以前很多的代码都放到Git里面了,里面有链接. 看了整整一天,刚开始 ...

  2. leetcode 124. Binary Tree Maximum Path Sum ----- java

    Given a binary tree, find the maximum path sum. For this problem, a path is defined as any sequence ...

  3. JavaWeb学习记录(二十二)——模式字符串与占位符

    一.Java代码案例 @Test    public void test10(){        int planet=7;        String event="a disturban ...

  4. IOS中货币高精度要求使用NSDecialNumber、

    float a = 0.01;        int b =99999999;        double c = 0.0;        c = a * b; //如果单纯的使用double会导致数 ...

  5. HTML5里autofocus属性

    转载:http://www.webhek.com/html5-autofocus/ HTML5给我们带来了一大堆神奇的东西.以前需要用JavaScript和Flash完成的任务,例如表单校验,INPU ...

  6. phpstrom 编辑器设置

    http://www.jb51.net/article/58069.htm 配置sublime主题  保存配置的路径为:C:\Users\Administrator\.WebIde100\config ...

  7. Agent admitted failure to sign using the key

    SSH生成id_rsa, id_rsa.pub后,连接服务器却报: Agent admitted failure to sign using the key 错误. 解决方法: 在当前用户下执行命令: ...

  8. ogg 、 Shareplex和DSG RealSync 对比

    主流数据库容灾(复制)工具对比     Oracle Golden Gate Quest Shareplex DSG RealSync   公司概要   公司介绍 GoldenGate公司成立于200 ...

  9. python扫描内网banner信息

    小菜自己无聊写着玩,主要纪念以前的逗逼学习,可以改IPy import mechanize import cookielib import socket import argparse import ...

  10. 如何用ABBYY把PDF转换成PPT

    在电子科技迅速发展的今天,文件格式转换并不是什么稀罕事,因为现在都是电子化办公,出现很多文件格式,但是不同的场合需要的格式不同,所以常常需要进行文件格式的转换.PDF转换成PPT也是众多文件格式转换中 ...