zoukankan      html  css  js  c++  java
  • Unity(IoC)

    一、什么是IoC?

         IoC(Inversion of Control,控制反转)又称“依赖注入”(Dependence Injection,DI)。

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

         依赖注入就是通过容器创建对象的,是通过在构造方法的参数,属性设置和接口等方式注入的。

         IoC的基本概念是:不创建对象,但是描述创建它们的方式。在代码中不直接与对象和服务连接,但在配置文件(或程序)中描述创建关系,容器负责将它们联系起来。

    二、什么是Unity?

         Unity是微软开发的一款轻量级、可扩展的IoC框架,可通过代码或者XML配置文件的形式来配置对象和对象直接的关系。

         在运行时直接调用容器即可获得我们需要的对象,以便建立松耦合的程序。

    三、创建Unity Demo

         1.新建控制台项目UnityDemo

         2.右键UnityDemo项目,选择“管理NuGet程序包”,安装Unity程序包

         3.新建几个接口IPhone,IHeadphone,IMicrophone,IPower

    public interface IHeadphone
        {
    
        }
     public interface IMicrophone
        {
    
        }
      public interface IPower
        {
    
        }
     public interface IPhone
        {
            /// <summary>
            /// 打电话
            /// </summary>
            void Call();
    
            IMicrophone iMicrophone { get; set; }
            IHeadphone iHeadphone { get; set; }
            IPower iPower { get; set; }
        }

        4.新建继承接口的类

     public class Headphone:IHeadphone
        {
    
        }
    public class Microphone: IMicrophone
        {
        }
    
    public class Power:IPower
        {
        }
    
     public class AndroidPhone : IPhone
        {
            public IHeadphone iHeadphone { get; set; }
    
            public IMicrophone iMicrophone { get; set; }
    
    
            public IPower iPower { get; set; }
    
            public AndroidPhone()
            {
                Console.WriteLine("{0}构造函数", this.GetType().Name);
            }
    
            public void Call()
            {
                Console.WriteLine("{0}打电话", this.GetType().Name); 
            }
        }
    
    public class ApplePhone : IPhone
        {
            [Dependency] //属性注入
            public IHeadphone iHeadphone { get; set; }
    
            public IMicrophone iMicrophone { get; set; }
    
            public IPower iPower { get; set; }
    
            public ApplePhone()
            {
                Console.WriteLine("{0}构造函数", this.GetType().Name);
            }
    
            [InjectionConstructor] //构造函数注入
            public ApplePhone(IMicrophone iMicrophone)
            {
                this.iMicrophone = iMicrophone;
    
                Console.WriteLine("{0}带参数构造函数", this.GetType().Name);
            }
    
            public void Call()
            {
                Console.WriteLine("{0}打电话", this.GetType().Name);
            }
    
            [InjectionMethod]  //属性注入
            public void Init(IPower iPower)
            {
                this.iPower = iPower;
            }
        }

     四、编程方式注册对应关系

          Unity有三种注入方式:1.属性注入,使用[Dependency]特性  2.构造方法注入,使用[InjectionConstructor]特性(没有此特性,默认使用参数最多的构造方法)  3.方法注入,使用[InjectionMethod]特性

          1.创建一个UnityContainer对象

          2.通过UnityContainer对象的RegisterType方法来注册对象和对象之间的关系

          3.通过UnityContainer对象的Resolve方法来获取指定对象关联的对象

    static void Main(string[] args)
            {
                try
                {
                    Console.WriteLine("********************AndroidPhone**********************");
                    {
                        IUnityContainer container = new UnityContainer();
                        container.RegisterType<IPhone, AndroidPhone>();
                        container.RegisterType<IHeadphone, Headphone>();
                        container.RegisterType<IMicrophone, Microphone>();
                        container.RegisterType<IPower, Power>();
                        IPhone phone = container.Resolve<IPhone>();
                        phone.Call();
                        //未注入   iHeadphone,iMicrophone,iPower 对象都为空             
                        Console.WriteLine("phone.iHeadphone == null? {0}", phone.iHeadphone == null);
                        Console.WriteLine("phone.iMicrophone == null? {0}", phone.iMicrophone == null);
                        Console.WriteLine("phone.iPower == null? {0}", phone.iPower == null);
                    }
    
                    Console.WriteLine("********************ApplePhone**********************");
                    {
                        IUnityContainer container = new UnityContainer();
                        container.RegisterType<IPhone, ApplePhone>();
                        container.RegisterType<IHeadphone, Headphone>();
                        container.RegisterType<IMicrophone, Microphone>();
                        container.RegisterType<IPower, Power>();
                        IPhone phone = container.Resolve<IPhone>();
                        phone.Call();
                        //通过属性注入,构造函数注入,方法注入   iHeadphone,iMicrophone,iPower 对象不为空    
                        Console.WriteLine("phone.iHeadphone == null? {0}", phone.iHeadphone == null);
                        Console.WriteLine("phone.iMicrophone == null? {0}", phone.iMicrophone == null);
                        Console.WriteLine("phone.iPower == null? {0}", phone.iPower == null);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                Console.ReadKey();
            }

      运行结果:

    五、通过配置文件配置对应关系

         项目结构:

        配置文件:

    <?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="IPhone" type="UnityDemo.Interface.IPhone,UnityDemo" />
          <add alias="IHeadphone" type="UnityDemo.Interface.IHeadphone,UnityDemo" />
          <add alias="IMicrophone" type="UnityDemo.Interface.IMicrophone,UnityDemo" />
          <add alias="IPower" type="UnityDemo.Interface.IPower,UnityDemo" />
    
          <add alias="AndroidPhone" type="UnityDemo.Service.AndroidPhone,UnityDemo" />
          <add alias="ApplePhone" type="UnityDemo.Service.ApplePhone,UnityDemo" />
          <add alias="Headphone" type="UnityDemo.Service.Headphone,UnityDemo" />
          <add alias="Microphone" type="UnityDemo.Service.Microphone,UnityDemo" />
          <add alias="Power" type="UnityDemo.Service.Power,UnityDemo" />
        </aliases>
        <!--容器-->
        <container name="MyContainer">
          <!--映射关系-->
          <register type="IPhone" mapTo="ApplePhone"/>
          <register type="IHeadphone" mapTo="Headphone"/>
          <register type="IMicrophone" mapTo="Microphone"/>
          <register type="IPower" mapTo="Power"/>
        </container>
      </unity>
    </configuration>

       调用代码:

    public static void ContainerConfiguration()
            {
                IUnityContainer container = new UnityContainer();
                ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap { ExeConfigFilename ="Unity.config"};
                Configuration configuration =  ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
                UnityConfigurationSection section =(UnityConfigurationSection)configuration.GetSection("unity");
                container.LoadConfiguration(section, "MyContainer");
                IPhone phone = container.Resolve<IPhone>();
                phone.Call();
                //通过属性注入,构造函数注入,方法注入   iHeadphone,iMicrophone,iPower 对象不为空    
                Console.WriteLine("phone.iHeadphone == null? {0}", phone.iHeadphone == null);
                Console.WriteLine("phone.iMicrophone == null? {0}", phone.iMicrophone == null);
                Console.WriteLine("phone.iPower == null? {0}", phone.iPower == null);
            }
  • 相关阅读:
    mysql workbench 建表时PK, NN, UQ, BIN, UN, ZF, AI
    Asan检测内存读越界
    C 实现 C++ 的面向对象特性(封装、继承、多态)
    VIBE算法
    Go 大坑 nil
    求二叉树中节点的最大距离
    计算[1,N]范围内含有7的数字的个数
    一组便于创建线程和线程池的简单封装函数
    用C#执行doc命令
    可以自由停靠的窗体!
  • 原文地址:https://www.cnblogs.com/marshhu/p/6811551.html
Copyright © 2011-2022 走看看