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>

最新文章

  1. Quartz Core框架之CALayer
  2. Hosts文件的使用
  3. HttpContext.Current.Cache 和HttpRuntime.Cache的区别
  4. Grunt之项目脚手架
  5. JSON和JSONP区别和联系
  6. SRAM与SDRAM的区别
  7. shell 验证ip
  8. Sequence
  9. 【干货】.NET开发通用组件发布(一) 介绍
  10. Find the k-th Smallest Element in the Union of Two Sorted Arrays
  11. 朴素贝页斯分类法 c++实现
  12. JavaScript实现360度全景图片展示效果
  13. Linux笔记(九) - 软件包管理
  14. KoaHub.JS用于Node.js的cron作业调度程序代码
  15. navicat for mysql只导出数据表结构(转)
  16. RT-thread 利用Scons 工具编译提示python编码错误解决办法
  17. python中的协程及实现
  18. Kafka中bootstrap-server、broker-list和zookeeper的区别
  19. tigervnc-server安装使用
  20. plsql developer 使用sys用户登录,报ORA-01031权限不足,解决sys(dba权限用户)远程登录报错。

热门文章

  1. B. Simple Molecules
  2. C++笔试题库之编程、问答题 100~150道
  3. Luogu P1542包裹快递【实数域二分】 By cellur925
  4. JavaSE基础知识结构
  5. C++ multiset通过greater、less指定排序方式,实现最大堆、最小堆功能
  6. c++模板专门化
  7. Python入门小练习-001-备份文件
  8. AtCoder Grand Contest 018 D - Tree and Hamilton Path
  9. UVA - 11082 Matrix Decompressing
  10. Little Elephant and Elections CodeForces - 258B