zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    利用.net Core 对程序集中的类 进行统一依赖注入
    接口中定义异步的方法
    在efcore 中创建类 通过实现IEntityTypeConfiguration<T>接口 实现实体类的伙伴类 实现FluentApi
    在vs2017 版本15.7.6中不支持2.1.0以上版本的net core sdk
    在.net core不同的版本中 webabi引用的包不同
    SQL语句中使用Group by
    DDD实战12 值对象不创建表,而是直接作为实体中的字段
    src与href的区别。
    cookies,sessionStorage 和 localStorage 的区别
    javascript阻止事件冒泡和浏览器的默认行为
  • 原文地址:https://www.cnblogs.com/guoyiwen/p/10436447.html
Copyright © 2011-2022 走看看