一、IOC介绍

IOC(Inversion of Control),中文译为控制反转,又称为“依赖注入”(DI =Dependence Injection)

IOC的基本概念是:不创建对象,但是描述创建它们的方式。

在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务。容器负责将这些联系在一起。

其原理是基于OO设计原则的The Hollywood Principle:Don't call us, we'll call you(别找我,我会来找你的)。

也就是说,所有的组件都是被动的(Passive),所有的组件初始化和调用都由容器负责。组件处在一个容器当中,由容器负责管理。

简单地说,就是应用本身不负责依赖对象的创建和维护,而是将其交给一个外部容器来负责。这样控制权就由应用转移到了外部IoC 容器,即控制权实现了所谓的反转。

比如在类型A 中需要使用类型B 的实例,而B 实例的创建并不由A 来负责,而是通过外部容器来创建。通过IoC 的方式实现针对目标Controller 的激活具有重要的意义。

二、获取Unity

目前流行的IoC 框架,如AutoFac、Castle Windsor、Unity、Spring.NET、StructureMap和Ninject 等。

可以直接在Nuget中获取到最新版本的Unity。我用的是Unity,不是Unity for mvc。

三、介绍Unity

Unit是微软patterns& practices组用C#实现的轻量级、可扩展的依赖注入容器,我们可以通过代码或者XML配置文件的形式来配置对象与对象之间的关系,

在运行时直接调用Unity容器即可获取我们所需的对象,以便建立松散耦合的应用程序。

对于小型项目:用代码的方式实现即可

对于中大型项目:使用配置文件比较好

Unity既然是一中Ioc框架,那么他同样满足Ioc的共性,依赖注入划分为3 种形式,即构造器注入、属性(设置)注入和接口注入。

四、Unity API(部分)

UnityContainer.RegisterType<ITFrom,TTO>();

UnityContainer.RegisterType< ITFrom, TTO>("keyName");

IEnumerable<T> databases = UnityContainer.ResolveAll<T>();

IT instance = UnityContainer.Resolve<IT>();

T instance = UnityContainer.Resolve<T>("keyName");

UnitContainer.RegisterInstance<T>("keyName",new T());

UnityContainer.BuildUp(existingInstance);

IUnityContainer childContainer1 = parentContainer.CreateChildContainer();

五、使用Untiy

如果是使用的NuGut安装的Unity库,那么在项目中将会自动添加引用

Microsoft.Practices.Unity.dll

Microsoft.Practices.Unity.Configuration.dll

Microsoft.Practices.Unity.RegistrationByConvention.dll

1、用编程方式实现注入

使用Unity来管理对象与对象之间的关系可以分为以下几步:

A、创建一个UnityContainer对象

B、通过UnityContainer对象的RegisterType方法来注册对象与对象之间的关系

C、通过UnityContainer对象的Resolve方法来获取指定对象关联的对象

注入代码如下:

/// <summary>
/// 商品
/// </summary>
public interface IProduct
{
string ClassName { get; set; }
string ShowInfo();
}
/// <summary>
/// 牛奶
/// </summary>
public class Milk : IProduct
{
public string ClassName { get; set; }
public void ShowInfo()
{
return string.Format("牛奶:{0}", ClassName);
}
}
/// <summary>
/// 糖
/// </summary>
public class Sugar : IProduct
{
public string ClassName { get; set; }
public void ShowInfo()
{
return string.Format("糖:{0}", ClassName);
}
} /// <summary>
/// 代码注入
/// </summary>
public string ContainerCode()
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IProduct, Milk>(); //默认注册(无命名),如果后面还有默认注册会覆盖前面的
container.RegisterType<IProduct, Sugar>("Sugar"); //命名注册 IProduct _product = container.Resolve<IProduct>(); //解析默认对象
_product.ClassName = _product.GetType().ToString();
string str1 = _product.ShowInfo();
IProduct _sugar = container.Resolve<IProduct>("Sugar"); //指定命名解析对象
_sugar.ClassName = _sugar.GetType().ToString();
string str2 = _sugar.ShowInfo();        StringBuilder strs = new StringBuilder();
       strs.Append(str1);
       strs.Append(str2);
IEnumerable<IProduct> classList = container.ResolveAll<IProduct>(); //获取容器中所有IProduct的注册的已命名对象
foreach (var item in classList)
{
item.ClassName = item.GetType().ToString();
strs.Append(item.ShowInfo());
}return strs.ToString();
}

  结果:牛奶:UnityTest.Milk 糖:UnityTest.Sugar 糖:UnityTest.Sugar

2、配置文件方式

通过配置文件配置Unity信息需要有以下几个步骤:

A、在配置文件<configSections> 配置节下注册名为unity的section

B、在<configuration> 配置节下添加Unity配置信息

C、在代码中读取配置信息,并将配置载入到UnityContainer中

配置文件内容如下:

<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> <!--声明容器-->
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/> </configSections> <unity>
<!--定义类型别名-->
<aliases>
<add alias="IProduct" type="UnityTest.IProduct,UnityTest" />
<add alias="Milk" type="UnityTest.Milk,UnityTest" />
<add alias="Sugar" type="UnityTest.Sugar,UnityTest" />
</aliases>
<!--容器-->
<container name="MyContainer">
<!--映射关系-->
<register type="IProduct" mapTo="Milk"></register>
<register type="IProduct" mapTo="Sugar" name="Sugar"></register>
</container>
</unity>

添加引用:

using System.Configuration;

using Microsoft.Practices.Unity.Configuration;

/// <summary>
/// 配置文件注入
/// </summary>
public string ContainerConfiguration()
{
//加载容器配置
IUnityContainer container = new UnityContainer();
container.LoadConfiguration("MyContainer"); UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");//获取指定名称的配置节
section.Configure(container, "MyContainer");//获取特定配置节下已命名的配置节<container name='MyContainer'>下的配置信息 IProduct classInfo = container.Resolve<IProduct>("Sugar");
classInfo.ClassName = classInfo.GetType().ToString();
return classInfo.ShowInfo();
}

  结果:糖:UnityTest.Sugar

如果系统比较庞大,那么对象之间的依赖关系可能就会很复杂,最终导致配置文件变得很大,所以我们需要将Unity的配置信息从App.config或web.config中分离出来到某一个单独的配置文件中,比如Unity.config,实现方式可以参考如下代码:

<?xml version="1.0" encoding="utf-8"?>
<configuration> <system.web>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2" />
</system.web> <configSections>
<!--声明容器-->
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>
</configSections> <unity>
<!--定义类型别名-->
<aliases>
<add alias="IProduct" type="UnityTest.IProduct,UnityTest" />
<add alias="Milk" type="UnityTest.Milk,UnityTest" />
<add alias="Sugar" type="UnityTest.Sugar,UnityTest" />
</aliases>
<!--容器-->
<container name="MyContainer">
<!--映射关系-->
<register type="IProduct" mapTo="Milk"></register>
<register type="IProduct" mapTo="Sugar" name="Sugar"></register>
</container>
</unity> </configuration>

注册代码:

/// <summary>
/// 配置文件注入
/// </summary>
public string ContainerConfiguration2()
{
IUnityContainer container = new UnityContainer();
string configFile = "Unity.config";
var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = configFile }; //从config文件中读取配置信息
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
//获取指定名称的配置节
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
//载入名称为FirstClass 的container节点
container.LoadConfiguration(section, "MyContainer"); IProduct classInfo = container.Resolve<IProduct>("Sugar");
classInfo.ClassName = classInfo.GetType().ToString();
return classInfo.ShowInfo();
}

  结果:糖:UnityTest.Sugar

来源:http://www.tuicool.com/articles/2AnAf26

参考:

http://www.cnblogs.com/qqlin/tag/IoC/

http://www.cnblogs.com/kyo-yo/archive/2010/11/10/Learning-EntLib-Tenth-Decoupling-Your-System-Using-The-Unity-PART2-Learn-To-Use-Unity-Two.html

Unity(一)介绍与基本使用的更多相关文章

  1. 依赖注入与Unity(一) 介绍

        在你学习依赖注入和Unity之前,你需要明白你为什么要使用它们.为了明白为什么要使用它们,你应该明白依赖注入和Unity能够帮助你解决什么类型的问题.作为介绍部分,这一章不会涉及太多关于Uni ...

  2. Socket.IO for Unity 简要介绍

    在项目中使用到了Socket.IO for unity这个Asset Store上免费的库,这里将简要的介绍一下它的结构,已经使用中的注意事项. 目录结构 上面为包的目录结构,简单的介绍一下具体的内容 ...

  3. [Unity-1] Unity简单介绍

    Unity是一套包含图形.声音.物理等功能的游戏引擎,提供了一个强大的关卡编辑器.支持大部分主流3D软件格式,使用C#或者JavaScript等高级语言实现脚本功能.使开发人员无需了解底层复杂技术,高 ...

  4. Unity插件介绍——Odin

    今天把玩了一款最近的热门插件——“Odin - Inspector and Serializer”,其功能强大到让人无语,简直是开发利器,屠龙宝刀!它的功能是扩展Inspector显示,它重写和增加了 ...

  5. unity工具介绍

    MemoryProfiler内存分析工具 行为树 behaviac github 场景动画编辑器 Snapdragon Profiler性能分析工具 VTune性能分析器 protobuf数据交换格式 ...

  6. 快速上手Unity原生Json库

    现在新版的Unity(印象中是从5.3开始)已经提供了原生的Json库,以前一直使用LitJson,研究了一下Unity用的JsonUtility工具类的使用,发现使用还挺方便的,所以打算把项目中的J ...

  7. Unity性能优化(4)-官方教程Optimizing graphics rendering in Unity games翻译

    本文是Unity官方教程,性能优化系列的第四篇<Optimizing graphics rendering in Unity games>的翻译. 相关文章: Unity性能优化(1)-官 ...

  8. Unity 相关经典博客资源总结(持续更新)

    就作为一个记录吧,把平时看过的Unity相关的一些好的Blog记录并分享. 好的论坛: Unity官方脚本  点评:这个不用说了,最核心的内容,理解整个Unity引擎的方方面面,梳理结构. Unity ...

  9. 【使用Unity开发Windows Phone上的2D游戏】(1)千里之行始于足下

    写在前面的 其实这个名字起得不太欠当,Unity本身是很强大的工具,可以部署到很多个平台,而不仅仅是可以开发Windows Phone上的游戏. 只不过本人是Windows Phone 应用开发出身, ...

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

    本节目录: AOP介绍 AOP基本原理 AOP框架 Castle Core Castle Windsor Autofac Unity AOP介绍 面向切面编程(Aspect Oriented Prog ...

随机推荐

  1. Dictionary 序列化与反序列化

    [转:http://blog.csdn.net/woaixiaozhe/article/details/7873582] 1.说明:Dictionary对象本身不支持序列化和反序列化,需要定义一个继承 ...

  2. 【python】类中@property使用

    在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改: s = Student() s.score = 9999 这显然不合逻辑.为了限制score的 ...

  3. struts2&&Hibernate Demo1

    这篇文章和<struts1&&Hibernate Demo1>基本类似,我这里只是拷贝代码了. 最核心的代码:LoginAction.java package action ...

  4. ASP.NET MVC+EF5 开发常用代码

      Asp.Net Mvc,EF 技术常用点总结 1.Asp.Net MVC a)获得当前控制器名和当前操作的名称(action) 1.Action 中 RouteData.Values[" ...

  5. JAVA 几种引用类型学习

    1.对象的强.软.弱和虚引用    在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从J ...

  6. [Tex学习]编号

    \documentclass{ctexart}\usepackage{enumerate}\begin{document}\begin{enumerate}[{case}1]\item new\ite ...

  7. Spring container vs SpringMVC container(webmvc container)

    Difference between applicationContext.xml and spring-servlet.xml in Spring Framework Scenario 1 In c ...

  8. South - 在 Django 中 Migrate Database

    Web 开发避免不了经常修改表结构,手工修改表结构不仅容易出错,而且涉及到多人协作开发时,这么土的做法很不经济. Django 的第三方 app South 就是专门做数据库表结构自动迁移的.Jaco ...

  9. 使用Atlas实现MySQL读写分离

    1.MySQL所在机器 192.168.29.128(Master) 192.168.29.129(Slave) 配置好主从同步,参考 http://www.cnblogs.com/luxh/p/40 ...

  10. VPS及LNMP(一)

    1.试用了搬瓦工.interserver.天翼云.网安互联之后,分别写下感受: 前两个是美国服务器,天翼云是国内服务器,网安互联是香港主机. a.搬瓦工非常便宜,512M的1年9.99刀,但是用了之后 ...