Ioc 之 Unity的依赖注入
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的依赖注入的更多相关文章
- IOC使用Unity 实现依赖注入
转自:http://www.cnblogs.com/techborther/archive/2012/01/06/2313498.html http://www.cnblogs.com/xishuai ...
- Entity Framework 实体框架的形成之旅--利用Unity对象依赖注入优化实体框架(2)
在本系列的第一篇随笔<Entity Framework 实体框架的形成之旅--基于泛型的仓储模式的实体框架(1)>中介绍了Entity Framework 实体框架的一些基础知识,以及构建 ...
- .NET 使用unity实现依赖注入
原文地址:http://www.cnblogs.com/wujy/p/3317795.html 一:理论部分 依赖注入:这是 Ioc 模式的一种特殊情况,是一种基于改变对象的行为而不改变类的内部的接口 ...
- ASP.NET MVC中使用Unity进行依赖注入的三种方式
在ASP.NET MVC中使用Unity进行依赖注入的三种方式 2013-12-15 21:07 by 小白哥哥, 146 阅读, 0 评论, 收藏, 编辑 在ASP.NET MVC4中,为了在解开C ...
- 运用Unity实现依赖注入[结合简单三层实例]
运用Unity实现依赖注入[结合简单三层实例] 一:理论部分 依赖注入:这是 Ioc 模式的一种特殊情况,是一种基于改变对象的行为而不改变类的内部的接口编程技术.开发人员编写实现接口的类代码,并基于接 ...
- Spring IOC(三)依赖注入
本系列目录: Spring IOC(一)概览 Spring IOC(二)容器初始化 Spring IOC(三)依赖注入 Spring IOC(四)总结 目录 1.AbstractBeanFactory ...
- Spring IOC(五)依赖注入
Spring IOC(五)依赖注入 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) 一.autowire 五种注入方式测试 ...
- 在 mvc 4 中使用 unity 进行依赖注入
在 mvc 4 中使用 unity 进行依赖注入 关于依赖注入的概念,这里就不再叙述了,我们用 mvc 4 结合 unity,使用构造函数来进行依 赖注入.具体步骤如下: 1. 首先建立 一个 mvc ...
- 深入浅出spring IOC中三种依赖注入方式
深入浅出spring IOC中三种依赖注入方式 spring的核心思想是IOC和AOP,IOC-控制反转,是一个重要的面向对象编程的法则来消减计算机程序的耦合问题,控制反转一般分为两种类型,依赖注入和 ...
随机推荐
- Android 应用程序窗体显示状态操作(requestWindowFeature()的应用)(转载)
转自:http://www.cnblogs.com/salam/archive/2010/11/30/1892143.html 我们在开发程序是经常会需要软件全屏显示.自定义标题(使用按钮等控件)和其 ...
- E20180426-hm
transition n. 过渡,转变,变迁; [语] 转换; [乐] 变调 flip vt. 按(开关); 快速翻转; 急挥; n. 空翻; 浏览; (射击时枪管的) 跳跃; 轻抛; win ...
- hdoj5024【BFS/暴力】
题意: 在可以行走的区域内,只能转一次90度的弯,问你最长这条路可以多长. 思路: 我们可以看到 /* 123 8 4 765 */ 转90度的路径会是横竖,也就是1-3-5-7; 还有斜的:2-4- ...
- 开挂的map
转自:http://blog.csdn.net/sunshinewave/article/details/8067862 #include<iostream> #include<ma ...
- bzoj 2084: [Poi2010]Antisymmetry【回文自动机】
manacher魔改,hash+二分都好写,但是我魔改了个回文自动机就写自闭了orz 根本上来说只要把==改成!=即可,但是这样一来很多停止条件就没了,需要很多特判手动刹车,最后统计一下size即可 ...
- bzoj 4903: [Ctsc2017]吉夫特【lucas+状压dp】
首先根据lucas, \[ C_n^m\%2=C_{n\%2}^{m\%2}*C_{n/2}^{m/2} \] 让这个式子的结果为计数的情况只有n&m==m,因为m的每一个为1的二进制位都需要 ...
- useradd user 错误解决
今天给安装Sequoiadb 软体时,出现添加用户和组失败,显示错误: cannot lock /et/passwd; try again later. 在网上查了一下,说是/etc/passwd 文 ...
- Codeforces Round #544 (Div. 3) B.Preparation for International Women's Day
链接:https://codeforces.com/contest/1133/problem/B 题意: 给n个数,和一个k,在n个数中选几对数,保证没对数相加可以整除k. 求最大能选几个数. 思路: ...
- fscanf
fscanf (PHP 4 >= 4.0.1, PHP 5, PHP 7) fscanf — 从文件中格式化输入 说明 mixed fscanf ( resource $handle , str ...
- python中的sort和sorted
共同点 都有三个参数, cmp用户自定义(指定函数),每个元素都会调用,效率没key高 key带一个参数的函数,用来为每个元素提取比较值 reverse=True 翻转 sort sort作用的 ...