zoukankan      html  css  js  c++  java
  • Unity IOC/DI使用

    一、IOC介绍

      IOC(Inversion of Control),中文译为控制反转,又称为“依赖注入”(DI =Dependence Injection)

      IOC的基本概念是:不创建对象,但是描述创建它们的方式。在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务。容器负责将这些联系在一起。

      其原理是基于OO设计原则的The Hollywood Principle:Don't call us, we'll call you(别找我,我会来找你的)。也就是说,所有的组件都是被动的(Passive),所有的组件初始化和调用都由容器负责。组件处在一个容器当中,由容器负责管理。

      简单地说,就是应用本身不负责依赖对象的创建和维护,而是将其交给一个外部容器来负责。这样控制权就由应用转移到了外部IoC 容器,即控制权实现了所谓的反转。比如在类型A 中需要使用类型B 的实例,而B 实例的创建并不由A 来负责,而是通过外部容器来创建。通过IoC 的方式实现针对目标Controller 的激活具有重要的意义。

    二、获取Unity

    目前流行的IoC 框架,如AutoFac、Castle Windsor、Unity、Spring.NET、StructureMap和Ninject 等。Unity 在Codeplex 上的地址为http://unity.codeplex.com/,我们可以下载相应的安装包和开发文档。当然,如果在您的visual studio 中安装了Nuget 包管理器,你可以直接在Nuget中获取到最新版本的Unity。

    三、介绍Unity

    Unit是微软patterns& practices组用C#实现的轻量级、可扩展的依赖注入容器,我们可以通过代码或者XML配置文件的形式来配置对象与对象之间的关系,在运行时直接调用Unity容器即可获取我们所需的对象,以便建立松散耦合的应用程序。

    对于小型项目:用代码的方式实现即可

    对于中大型项目:使用配置文件比较好

    Unity既然是一中Ioc框架,那么他同样满足Ioc的共性,依赖注入划分为3 种形式,即构造器注入、属性(设置)注入和接口注入。

    四、Unity API

    UnityContainer.RegisterType<ITFrom,TTO>();

    UnityContainer.RegisterType< ITFrom, TTO >();

    UnityContainer.RegisterType< ITFrom, TTO >("keyName");

    IEnumerable<T> databases = UnityContainer.ResolveAll<T>();

    IT instance = UnityContainer.Resolve<IT>();

    T instance = UnityContainer.Resolve<T>("keyName");

    UnitContainer.RegisterInstance<T>("keyName",new T());

    UnityContainer.BuildUp(existingInstance);

    IUnityContainer childContainer1 = parentContainer.CreateChildContainer();

    五、使用Unity

    如果是项目的引用那里,右击选择管理NuGet程序包进行安装的,就会自动添加

    Microsoft.Practices.Unity.dll和Microsoft.Practices.Unity.Configuration.dll以及Microsoft.Practices.Unity.RegistrationByConvention的引用

    如果你是直接在VS工具里面使用NuGet下载安装的话,相关文件会保存在你当前这个解决方案下面的packages夹中,
    你必须手动添加引用。引用路径:packagesUnity.3.5.1404.0lib et45

    新建控制台程序UnityDemo,并依次新建一个接口IProduct,两个类Milk、Sugar

    /// <summary>
        /// 商品
        /// </summary>
       public interface IProduct
        {
            string ClassName { get; set; }
            void ShowInfo();
        }
        /// <summary>
        /// 牛奶
        /// </summary>
       public class Milk:IProduct
        {
            public string ClassName { get; set; }
    
            public void ShowInfo()
            {
               Console.WriteLine("牛奶:{0}", ClassName);
            }
        }
        /// <summary>
        ////// </summary>
       public class Sugar:IProduct
        {
           public string ClassName { get; set; }
    
           public void ShowInfo()
           {
               Console.WriteLine("糖:{0}", ClassName);
           }
        }

    (1)用编程方式实现注入

    使用Unity来管理对象与对象之间的关系可以分为以下几步:

          A、创建一个UnityContainer对象

          B、通过UnityContainer对象的RegisterType方法来注册对象与对象之间的关系

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

     注入代码如下:

    /// <summary>
            /// 代码注入
            /// </summary>
            public static void ContainerCode()
            {
                IUnityContainer container = new UnityContainer();
    
                container.RegisterType<IProduct, Milk>();  //默认注册(无命名),如果后面还有默认注册会覆盖前面的
                container.RegisterType<IProduct, Sugar>("Sugar");  //命名注册
    
                IProduct _product = container.Resolve<IProduct>();  //解析默认对象
                _product.ClassName = _product.GetType().ToString();
                _product.ShowInfo();
    
                IProduct _sugar = container.Resolve<IProduct>("Sugar");  //指定命名解析对象
                _sugar.ClassName = _sugar.GetType().ToString();
                _sugar.ShowInfo();
    
                IEnumerable<IProduct> classList = container.ResolveAll<IProduct>(); //获取容器中所有IProduct的注册的已命名对象
    
                foreach (var item in classList)
                {
                   item.ClassName = item.GetType().ToString();
                   item.ShowInfo();
                }
            }

    Prome.cs:

    class Program
        {
            static void Main(string[] args)
            {
                ContainerCode();
            }
      }

    效果图如下:

    (2)配置文件方式

    通过配置文件配置Unity信息需要有以下几个步骤:

           A、在配置文件<configSections> 配置节下注册名为unity的section

           B、在<configuration> 配置节下添加Unity配置信息

           C、在代码中读取配置信息,并将配置载入到UnityContainer中

    配置文件内容如下:

    <?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 alias="Milk" type="UnityDemo.Milk,UnityDemo" />
          <add alias="Sugar" type="UnityDemo.Sugar,UnityDemo" />
        </aliases>
        <!--容器-->
        <container name="MyContainer">
          <!--映射关系-->
          <register type="Iproduct"  mapTo="Milk"></register>
          <register type="Iproduct"  mapTo="Sugar" name="Sugar"></register>
        </container>
      </unity>
      <!--<startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
      </startup>-->
    </configuration>

    先添加System.Configuration引用

    配置文件注入代码:

    /// <summary>
            /// 配置文件注入
            /// </summary>
            public static void ContainerConfiguration()
            {
                IUnityContainer container = new UnityContainer();
                container.LoadConfiguration("MyContainer");
                UnityConfigurationSection section
                  = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");//获取指定名称的配置节   
                section.Configure(container, "MyContainer");//获取特定配置节下已命名的配置节<container name='MyContainer'>下的配置信息
    
                IProduct classInfo = container.Resolve<IProduct>("Sugar");
                classInfo.ShowInfo();
            }

    如果系统比较庞大,那么对象之间的依赖关系可能就会很复杂,最终导致配置文件变得很大,所以我们需要将Unity的配置信息从App.config或web.config中分离出来到某一个单独的配置文件中,比如Unity.config,实现方式可以参考如下代码

    #region
                IUnityContainer container = new UnityContainer();
                string configFile = "Unity.config";
                var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = configFile };
                //从config文件中读取配置信息
                Configuration configuration =ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
                //获取指定名称的配置节
                UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection("unity");
                //载入名称为FirstClass 的container节点
                container.LoadConfiguration(section, "MyContainer");
    
     #endregion

    转自:http://www.cnblogs.com/jiekzou/

  • 相关阅读:
    Java高级之类结构的认识
    14.8.9 Clustered and Secondary Indexes
    14.8.4 Moving or Copying InnoDB Tables to Another Machine 移动或者拷贝 InnoDB 表到另外机器
    14.8.3 Physical Row Structure of InnoDB Tables InnoDB 表的物理行结构
    14.8.2 Role of the .frm File for InnoDB Tables InnoDB 表得到 .frm文件的作用
    14.8.1 Creating InnoDB Tables 创建InnoDB 表
    14.7.4 InnoDB File-Per-Table Tablespaces
    14.7.2 Changing the Number or Size of InnoDB Redo Log Files 改变InnoDB Redo Log Files的数量和大小
    14.7.1 Resizing the InnoDB System Tablespace InnoDB 系统表空间大小
    14.6.11 Configuring Optimizer Statistics for InnoDB 配置优化统计信息用于InnoDB
  • 原文地址:https://www.cnblogs.com/whai/p/5190110.html
Copyright © 2011-2022 走看看