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="Configioc.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
    }
}
View Code

调用示例:

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

原文地址:https://www.cnblogs.com/guoyiwen/p/10436447.html