Unity依赖注入(笔记)

时间:2023-03-09 18:09:39
Unity依赖注入(笔记)

一.介绍

控制反转(Inversion of Control,简称IoC):整洁架构思想,不允许内部获知外部的存在,这就导致了我们必须在内层定义与外层交互的接口,通过依赖注入的方式将外层实现注入到内部来。

依赖注入(Dependency Injection,简称DI): 高层通过接口隔离具体实现的依赖,就意味着具体实现转移到了外部,究竟使用哪一个具体实现,由外部调用者来决定,只有在运行调用者代码时才将外面的依赖传递给高层。

依赖倒置原则(Dependency Inversion Principle,DIP) : 高层模块不应该依赖于底层模块,两者应该依赖于抽象。本质:我们要依赖不变或稳定的元素(类,模块或层),抽象不应该依赖细节,细节应该与抽象。

二.Unity使用介绍

使用Nuget包安装以下组件:

Unity : 5.8.6

Unity.Interception :  5.5.3

<!--Unity 配置文件-->
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
</configSections>
<unity>
<sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/>
<containers>
<container name="testContainer">
<register type="Interface.IPhone,Interface" mapTo="Services.AndroidPhone, Services" />
<register type="Interface.IPhone,Interface" mapTo="Services.TestPhone, Services" name="TestPhone"/>
</container>
</containers>
</unity>
</configuration>

  

<!--Unity 配置文件讲解-->
<unity>
<sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/>
<containers>
<container name="容器名称">
<register type="接口的命名空间(namespace).接口名,接口的命名空间" mapTo="实现类的命名空间.实现类名, 实现类的命名空间" />
<register type="Interface.IPhone,Interface" mapTo="Services.TestPhone, Services" name="TestPhone"/>
</container>
</containers>
</unity>
</configuration>

  

封装UnityIocHelper调用类:

using System;
using System.Configuration;
using System.IO;
using Microsoft.Practices.Unity.Configuration;
using Unity;
using Unity.Resolution; namespace MyIOC.Untiy
{
/// <summary>
/// 描 述:UnityIoc
/// </summary>
public class UnityIocHelper
{
#region 构造方法
/// <summary>
/// 构造方法
/// </summary>
/// <param name="containerName">容器名称</param>
private UnityIocHelper(string containerName)
{ ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\\Unity.Config");//找配置文件的路径
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
//UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
// <unity configSource="Config\ioc.config" />
if (section.Containers.Count > 0)
{
_container = new UnityContainer();
section.Configure(_container, containerName);
}
}
#endregion #region 属性
/// <summary>
/// 容器
/// </summary>
private readonly IUnityContainer _container;
/// <summary>
/// 容器实例
/// </summary>
private static readonly UnityIocHelper instance = new UnityIocHelper("testContainer"); /// <summary>
/// UnityIoc容器实例
/// </summary>
public static UnityIocHelper Instance
{
get { return instance; }
} #endregion #region 获取对应接口的具体实现类
/// <summary>
/// 获取实现类(默认映射)
/// </summary>
/// <typeparam name="T">接口类型</typeparam>
/// <returns>接口</returns>
public T GetService<T>()
{
return _container.Resolve<T>();
}
/// <summary>
/// 获取实现类(默认映射)带参数的
/// </summary>
/// <typeparam name="T">接口类型</typeparam>
/// <param name="parameter">参数</param>
/// <returns>接口</returns>
public T GetService<T>(params ParameterOverride[] parameter)
{
return _container.Resolve<T>(parameter);
}
/// <summary>
/// 获取实现类(指定映射)带参数的
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="name"></param>
/// <param name="parameter"></param>
/// <returns>接口</returns>
public T GetService<T>(string name, params ParameterOverride[] parameter)
{
return _container.Resolve<T>(name, parameter);
}
#endregion #region 判断接口是否被注册了
/// <summary>
/// 判断接口是否被实现了
/// </summary>
/// <typeparam name="T">接口类型</typeparam>
/// <returns>bool</returns>
public bool IsResolve<T>()
{
return _container.IsRegistered<T>();
}
/// <summary>
/// 判断接口是否被实现了
/// </summary>
/// <typeparam name="T">接口类型</typeparam>
/// <param name="name">映射名称</param>
/// <returns></returns>
public bool IsResolve<T>(string name)
{
return _container.IsRegistered<T>(name);
}
#endregion
}
}

调用示例:

var android = UnityIocHelper.Instance.GetService<IPhone>();//不带参数,默认取容器的没用name的,但只能有一个,不然会异常.
android.Call();//AndroidPhone
var android = UnityIocHelper.Instance.GetService<IPhone>("TestPhone"); //取容器内名称匹配的.
android.Call();//TestPhone

三.Unity实现AOP

<!--Unity 配置文件-->
<container name="ContainerAOP">
<extension type="Interception"/>
<register type="Interface.IPhone,Interface" mapTo="Services.AndroidPhone, Services">
<interceptor type="InterfaceInterceptor"/>
<interceptionBehavior type="AOP.LogAfterBehavior,AOP"/>
<interceptionBehavior type="AOP.LogBeforeBehavior,AOP"/>
</register>
</container>

  

调用示例:

  var androidAOP = UnityIocHelper.AOPInstance.GetService<IPhone>();//跟普通调用一样.
androidAOP.Call();

四.Unity实现单例

 <container name="testContainer">
<register type="Interface.IPhone,Interface" mapTo="Services.AndroidPhone, Services" >
<lifetime type="singleton" />
</register>
</container>

  

五.源码下载:

https://github.com/gyw1309631798/MyIOC