• Unity依赖注入


    什么是IOC

      IOC(Inversion Of Control 控制反转):又被成为依赖注入(DI:Dependence Injection)

      控制反转就是创建对象的的权利有开发人员控制,转到了由容器控制。

      不创建对象,但描述创建他们的方式,代码不直接与对象和服务关联,在配置文件描述某个组件需要那一项服务,由容器把他们关联到一起,

      其中一个重要思想是(别来找我,我回来找你)

      比如A类型中使用B类型,而B的实例类型并不由A来创建,交给容器进行创建和管理,  

    通过代码和配置文件进行注入

      通过nuget引入Unity

        

      //配置文件的方式需要引入Microsoft.Practices.Unity.dll、Microsoft.Practices.Unity.Configuration.dll

      首先创建IProduct接口,Milk、Sugar类继承IProduct

      1、代码注入

     public interface IProduct
        {
            string ClassName { get; set; }
    
            void show();
        }
    
       public class Milk:IProduct
        {
            public string ClassName { get; set; }
           
    
            public void show()
            {
                Console.WriteLine("牛奶:"+ClassName);
            }
        }
    
       public class Sugar : IProduct
        {
            public string ClassName { get; set; }
    
            public void show()
            {
                Console.WriteLine("糖:" + ClassName);
            }
        }

    //注入和获取需要用到同一个容器

    using Microsoft.Practices.Unity;
    using System;
    using System.Collections.Generic;
    //using Unity;
    
    namespace UnityDemo
    {
        /// <summary>
        /// 依赖注入
        /// </summary>
        public   class ContainerCode
        {
          static  IUnityContainer unityContainer = new UnityContainer();
            public static void Init()
            {
                //默认方式 无名命
                unityContainer.RegisterType<IProduct, Milk>();
    
                //命名方式
                unityContainer.RegisterType<IProduct, Sugar>("sugar");
                
            }
    
    
            public static void Get()
            {
                //获取无命名方式
               IProduct product= unityContainer.Resolve<IProduct>();
                product.ClassName = product.GetType().Name;
                product.show();
    
                //命名方式
                IProduct _sugar = unityContainer.Resolve<IProduct>("sugar");
                _sugar.ClassName = _sugar.GetType().Name;
                _sugar.show();
                Console.WriteLine("_________________________________");
                Console.ForegroundColor = ConsoleColor.Blue;
                //获取容器中已注册的已命名对象
                IEnumerable<IProduct> products = unityContainer.ResolveAll<IProduct>();
                foreach (var item in products)
                {
                    item.ClassName = item.GetType().Name;
                    item.show();
                }
    
            }
    
        }
    }
    View Code

    2、配置文件注入

      在配置文件App.config或 Web.config中的configuration节点下添加

      其中configSections节点必须放在第一个位置,不然会报错

      配置节点详细图(顺手保存的(^_−)☆)

      

      如下app.config内容:

        

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    
      <!--必须放在第一个位置-->
      <configSections>
        
        <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>
      </configSections>
      <unity>
        <aliases>
          <!--定义类型别名-->
          <add alias="Iproduct" type="UnityDemo.IProduct,UnityDemo"></add>
          <add alias="Milk" type="UnityDemo.Milk,UnityDemo"></add>
          <add alias="Sugar1" type="UnityDemo.Sugar,UnityDemo"></add>
        </aliases>
        <!--容器-->
        <container name="MyContainer">
          <!--映射关系,与上面别名对应-->
          <register type="Iproduct" mapTo="Milk"></register><!--无命名方式-->
          <register type="Iproduct" mapTo="Sugar1" name="_Sugar"></register>
        </container>
      </unity>
      
      
      <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
      </startup>
    </configuration>

    用到的引用

    using System.Configuration;

    using Microsoft.Practices.Unity;

    using Microsoft.Practices.Unity.Configuration;

    using System.IO;

      

    /// <summary>
            /// 配置文件注入
            /// </summary>
            public static void Config()
            {
                //初始化容器
                IUnityContainer unityContainer = new UnityContainer();
    
                //获取指定名称的节点
                UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
                //获取设置的容器名
                section.Configure(unityContainer, "MyContainer");
    
                //  section.Containers.Default.Configure(unityContainer);
                //获取命名为_Sugar
                IProduct product = unityContainer.Resolve<IProduct>("_Sugar");
                product.ClassName = product.GetType().Name;
                product.show();
                //获取默认的
                IProduct product1 = unityContainer.Resolve<IProduct>();
                product1.ClassName = product.GetType().Name;
                product1.show();
    
            }

    配置文件通过会很大,可以单独放到一个文件中,在根目录创建Unity.config

        

       具体代码

      

     public static void Config1()
            {
                //将单独的config配置放在外面
    
                IUnityContainer unityContainer = new UnityContainer();
               // string configFile = "Unity.config";
    
                //获取文件路径,绝对
               string filePath= Path.GetFullPath("../../Unity.config");
                var fileMap = new ExeConfigurationFileMap(filePath);
                fileMap.ExeConfigFilename = "Unity.config";//指定文件名
                //从config读取配置信息
                Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
    
    
                UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection("unity");
    
                section.Configure(unityContainer, "MyContainer");
    
                //  section.Containers.Default.Configure(unityContainer);
                IProduct product = unityContainer.Resolve<IProduct>("_Sugar");
                product.ClassName = product.GetType().Name;
                product.show();
    
                IProduct product1 = unityContainer.Resolve<IProduct>();
                product1.ClassName = product.GetType().Name;
                product1.show();
    
            }

      

    使用构造函数(有参)进行注入

      首先把上面容器进行封装一下,添加一个UnityContainerHelp类

      

    using Microsoft.Practices.Unity;
    using Microsoft.Practices.Unity.Configuration;
    using System.Collections.Generic;
    using System.Configuration;
    using System.IO;
    
    namespace UnityDemo
    {
        public class UnityContainerHelp
        {
            private IUnityContainer unityContainer;
    
            public UnityContainerHelp()
            {
                unityContainer = new UnityContainer();
    
                //获取文件路径,绝对
                string filePath = Path.GetFullPath("../../Unity.config");
                var fileMap = new ExeConfigurationFileMap(filePath);
                fileMap.ExeConfigFilename = "Unity.config";//指定文件名
                //从config读取配置信息
                Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
                UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection("unity");
                section.Configure(unityContainer, "MyContainer");
            }
    
    
            public T GetServer<T>()
            {
                return unityContainer.Resolve<T>();
            }
            /// <summary>
            /// 配置文件的名称
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="name"></param>
            /// <returns></returns>
            public T GetServer<T>(string name)
            {
                return unityContainer.Resolve<T>(name);
            }
    
            public T GetServer<T>(Dictionary<string,object> paramateList)
            {
                var lis = new Microsoft.Practices.Unity.ParameterOverrides();
                foreach (var item in paramateList)
                {
                    lis.Add(item.Key, item.Value);
                }
                return unityContainer.Resolve<T>(lis);
            }
    
    
        }
    }
    View Code

        创建接口和类

         *Unity会默认使用构造函数参数最多的一个进行注入

    using System;
    using Unity;
    
    namespace UnityDemo
    {
    
        public interface ITest
        {
             String Name { get; set; }
             int Age { get; set; }
    
            void ShowInfo();
    
    
        }
    
        public class Test : ITest
        {
    
           
            public Test()
            {
    
            }
            [InjectionConstructor]
            public Test(string Name,int Age)
            {
                this.Name = Name;
                this.Age = Age;
            }
            public string Name { get ; set ; }
            public int Age { get; set; }
    
            public void ShowInfo()
            {
                Console.WriteLine("我是构造函数中的name:{0},我是age{1}",this.Name,this.Age);
            }
    
           
        }
    }

      修改配置文件

        添加 以下节点

          

       <add alias="ITest" type="UnityDemo.ITest,UnityDemo"></add>
          <add alias="Test" type="UnityDemo.Test,UnityDemo"></add>

      

      <register type="ITest" mapTo="Test" ></register>

      Program调用

      需要注意一下:key必须和构造函数参数大小写保持一致

           //构造函数注入
                Dictionary<string, object> parameterList = new Dictionary<string, object>();
                parameterList.Add("Name", "彭于晏");
                parameterList.Add("Age", 18);
               ITest test= unityContainerHelp.GetServer<ITest>(parameterList);
                test.ShowInfo();

      

      

      

      

      

  • 相关阅读:
    常用软件的安装(windows/linux)
    常用软件的安装(windows/linux)
    图像块的访问(填充 padding,步长 stride,窗 Window/kernel/filter)
    hdu4620 Fruit Ninja Extreme
    java中的object类
    [置顶] android 自定义TextView
    [置顶] think in java interview-高级开发人员面试宝典(八)
    POJ 2112 Optimal Milking (二分+最短路径+网络流)
    BitHacks--位操作技巧
    hdu 4614 Vases and Flowers (二分 线段树)
  • 原文地址:https://www.cnblogs.com/zhangmm96/p/11508276.html
Copyright © 2020-2023  润新知