Unity是微软官方提供的一个Ioc容器,用来实现依赖注入,减少代码之间的耦合程度。使用Unity实现Ioc方式有两种,一种是使用代码方式实现,一种是利用配置文件来实现。

  我们先来看一下代码方式是如何实现的。我们先定义 IPay接口,IOrder接口,再定义WeChatPay,AliPay,Order三个类。

   /// <summary>
/// 支付接口
/// </summary>
public interface IPay
{
string Pay();
} public interface IOrder
{
string ToPay();
}
    /// <summary>
/// 微信支付
/// </summary>
public class WeChatPay :IPay
{
public string Pay()
{
return "微信支付";
}
}
    /// <summary>
/// 支付宝支付
/// </summary>
public class AliPay : IPay
{
public string Pay()
{
return "支付宝支付";
}
}
/// <summary>
/// 订单
/// </summary>
public class Order : IOrder
{
/// <summary>
/// 订单支付方式
/// </summary>
public IPay _iPay; //构造函数注入:可以不写,因为Unity解析时默认会找参数最多的构造函数
[InjectionConstructor]
public Order(IPay iPay)
{
_iPay = iPay;
} [Dependency]//属性注入
public IPay _iPayProperty { get; set; } [InjectionMethod]//方法注入
public void PayInit(IPay ipay)
{
this._iPay = ipay;
} public string ToPay()
{
return this._iPay.Pay();
}
}

  接着,我们可以使用代码的方式来使用Unity

 //创建一个Unity空容器
IUnityContainer container = new UnityContainer(); //向Unity容器注入WeChatPay
container.RegisterType<IPay, WeChatPay>();
//向Unity容器注入AliPay,使用命名注册,解析的时候也需要使用命名获取实例
container.RegisterType<IPay, AliPay>("alipay"); var obj = container.Resolve<IPay>();
Console.WriteLine(obj.Pay());
obj = container.Resolve<IPay>("alipay");
Console.WriteLine(obj.Pay()); container.RegisterType<IOrder, Order>();
//Unity解析的时候会按照:构造函数注入 --> 属性注入 --> 方法注入的顺序进行解析
var order = container.Resolve<IOrder>();
Console.WriteLine($"Order.ToPay: {order.ToPay()}");

Console.ReadLine();

  运行得到结果

  那么,Unity注入类型的生命周期有哪些呢?

//生命周期
IUnityContainer container = new UnityContainer(); //默认瞬时,每一次都是全新生成
container.RegisterType<IOrder, Order>();
container.RegisterType<IOrder, Order>(new TransientLifetimeManager()); //容器单例
container.RegisterType<IOrder, Order>(new ContainerControlledLifetimeManager()); //线程单例
container.RegisterType<IOrder, Order>(new PerThreadLifetimeManager());
var phone1 = container.Resolve<IPhone>();
var phone2 = container.Resolve<IPhone>();
Console.WriteLine(object.ReferenceEquals(phone1, phone2)); //结果为true //分级容器单例
container.RegisterType<IOrder, Order>(new HierarchicalLifetimeManager());
IUnityContainer childContainer = container.CreateChildContainer(); //外部可释放单例
container.RegisterType<IOrder, Order>(new ExternallyControlledLifetimeManager()); //循环引用 不推荐
container.RegisterType<IOrder, Order>(new PerResolveLifetimeManager());

  接下来我们再来看下Unity使用配置文件的方式该如何实现依赖注入。我们在项目中新建一个文件夹Config,然后再创建unity.config文件。

<configuration>
<configSections>
<!--<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>-->
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
</configSections>
<unity>
<!--<sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration"/>-->
<sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/>
<containers> <container name="IocContainer">
<!-- 格式:类名,程序集名称 -->
<register type="IocDemo.IService.IOrder,IocDemo.IService" mapTo="IocDemo.Service.Order, IocDemo.Service"/>
<register type="IocDemo.IService.IPay,IocDemo.IService" mapTo="IocDemo.Service.AliPay, IocDemo.Service" name="alipay"/>
<register type="IocDemo.IService.IPay, IocDemo.IService" mapTo="IocDemo.Service.WeChatPay, IocDemo.Service"/>
</container>
</containers>
</unity>
</configuration>

  然后在程序中使用ExeConfigurationFileMap来装载该配置文件

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "Config\\unity.config");//找配置文件的路径
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName); IUnityContainer container = new UnityContainer();
section.Configure(container, "IocContainer"); IOrder order = container.Resolve<IOrder>();
Console.WriteLine(order.ToPay()); IPay aliPay = container.Resolve<IPay>("alipay");
Console.WriteLine(aliPay.Pay()); Console.ReadLine();

  我们也可以在配置文件中指定生命周期,构造函数初始值

  <register type="IocDemo.IService.IOrder,IocDemo.IService" mapTo="IocDemo.Service.Order,IocDemo.Service">
<lifetime type="transient" />
<constructor>
<!--<param name="id" type="System.Int32" value="" />-->
<param name="iPay" type="IocDemo.IService.IPay,IocDemo.IService"></param>
</constructor>
</register>

Ioc 之 Unity的依赖注入的更多相关文章

  1. IOC使用Unity 实现依赖注入

    转自:http://www.cnblogs.com/techborther/archive/2012/01/06/2313498.html http://www.cnblogs.com/xishuai ...

  2. Entity Framework 实体框架的形成之旅--利用Unity对象依赖注入优化实体框架(2)

    在本系列的第一篇随笔<Entity Framework 实体框架的形成之旅--基于泛型的仓储模式的实体框架(1)>中介绍了Entity Framework 实体框架的一些基础知识,以及构建 ...

  3. .NET 使用unity实现依赖注入

    原文地址:http://www.cnblogs.com/wujy/p/3317795.html 一:理论部分 依赖注入:这是 Ioc 模式的一种特殊情况,是一种基于改变对象的行为而不改变类的内部的接口 ...

  4. ASP.NET MVC中使用Unity进行依赖注入的三种方式

    在ASP.NET MVC中使用Unity进行依赖注入的三种方式 2013-12-15 21:07 by 小白哥哥, 146 阅读, 0 评论, 收藏, 编辑 在ASP.NET MVC4中,为了在解开C ...

  5. 运用Unity实现依赖注入[结合简单三层实例]

    运用Unity实现依赖注入[结合简单三层实例] 一:理论部分 依赖注入:这是 Ioc 模式的一种特殊情况,是一种基于改变对象的行为而不改变类的内部的接口编程技术.开发人员编写实现接口的类代码,并基于接 ...

  6. Spring IOC(三)依赖注入

    本系列目录: Spring IOC(一)概览 Spring IOC(二)容器初始化 Spring IOC(三)依赖注入 Spring IOC(四)总结 目录 1.AbstractBeanFactory ...

  7. Spring IOC(五)依赖注入

    Spring IOC(五)依赖注入 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) 一.autowire 五种注入方式测试 ...

  8. 在 mvc 4 中使用 unity 进行依赖注入

    在 mvc 4 中使用 unity 进行依赖注入 关于依赖注入的概念,这里就不再叙述了,我们用 mvc 4 结合 unity,使用构造函数来进行依 赖注入.具体步骤如下: 1. 首先建立 一个 mvc ...

  9. 深入浅出spring IOC中三种依赖注入方式

    深入浅出spring IOC中三种依赖注入方式 spring的核心思想是IOC和AOP,IOC-控制反转,是一个重要的面向对象编程的法则来消减计算机程序的耦合问题,控制反转一般分为两种类型,依赖注入和 ...

随机推荐

  1. E20180424-hm

    thumb n. 拇指; (手套的) 拇指部份; trigger  vt. 引发,触发; 扣…的扳机; 发射或使爆炸(武器或爆炸性弹药);      n. (枪) 扳机; 起动装置,扳柄; 引发其他事 ...

  2. Cannot call value of non-function type 'UITextView'报错

    iOS里面的开发,类写到一半就报错这个.后来发现是因为重名的时候召唤对象不明确的问题.先贴代码,晚点再说 出错点 //ヒントをクリアするためのイニシャライザ init (clearStr: UITex ...

  3. 洛谷 P1314 聪明的质监员【二分+前缀和】

    真是zz, 题目很显然是二分W,然后判断,我一开始是用线段树维护当前w[i]>W的个数和v(公式就是区间满足要求的个数*满足要求的v的和),然后T成70 后来想到树状数组差分常数或许会小,于是改 ...

  4. poj1850 Code【组合数学】By cellur925

    题意: * 按照字典序的顺序从小写字母 a 开始按顺序给出序列 (序列中都为升序字符串)* a - 1* b - 2* ...* z - 26* ab - 27* ...* az - 51* bc - ...

  5. bzoj3343 教主的魔法【分块入门】By cellur925

    题意:维护一个数列,给出维护区间加法,询问区间内大于等于某个值的元素个数. 算法:分块.因为本题第二问显然可以用二分的思想,但是这貌似并不符合区间可加性,线段树好像就不好用了呢.所以本蒟蒻学习了分块. ...

  6. Hibernate中表与表之间的关联一对多,级联保存和级联删除

    1:Hibernate的一对多操作(重点) 一对多映射配置 第一步:创建两个实体类:客户和联系人(例)以客户为一,联系人为多: package com.yinfu.entity; public cla ...

  7. 【Nginx】解决Post请求变Get的问题

    默认情况下Nginx会把post请求做一次重定向操作,然后后端收到的就成了Get请求,还会导致一些参数的遗漏. 日志如下: 172.16.1.108 - - [11/Jan/2019:18:27:09 ...

  8. 统计Apache或nginx日志里访问次数最多的前十个IP

    1.根据访问IP统计UV awk '{print $1}' access.log|sort | uniq -c |wc -l 2.统计访问URL统计PV awk '{print $7}' access ...

  9. C# ref和out传递参数总结

    如有雷同,不胜荣幸,若转载,请注明 C#中ref和out传递参数总结,两个都可用来传递参数,ref使用时必须先进行初始化,out则不需要,只要在返回之前赋值即可,文字废话到此,下面直接上例子 ref例 ...

  10. python实现汉诺塔(递归)

    def hanoi(n, A, B, C): if n > 0: hanoi(n-1, A, C, B) print("%s->%s" % (A, C)) hanoi( ...