• 微软企业库4.1学习笔记(二十五)Unity依赖注入模块2


    Unity模块的亮点

      Unity模块包括了下面的特点

    •   提供了一个创建对象,以及依赖的对象的方法
    •   提供的RegisterType方法用来在容器中注册类型和映射,Resolve方法可以返回任何依赖对象的实例。
    •   提供控制反转IOC功能,通过预先配置注入类的对象来实现。你可以在构造函数中指明一个类或者接口(构造函数注入),或者是使用attribute的属性注入,和方法调用注入。
    •   支持容器继承,容器可以有子容器,支持对象从子容器传递到父容器中。
    •   可以从标准的配置文件中读取信息,例如xml文件
    •   对类的定义没有任何要求。在类上不需要添加attribute(除非使用属性注入或者是方法调用注入),在类声明中没有任何限制。
    •   支持自定义容器,例如,你可以在方法中实现额外的对象构造,和容器功能,例如容器的缓存功能。

      什么时候使用Unity模块

      依赖注入提供了简化代码的机会,抽象对象之间的依赖,自动产生依赖对象的实例。但是,处理的过程对性能上有一点小的损失,而且可能会使得只需要简单依赖的地方变得复杂。

      通常来说,在下列情况你应该使用Unity模块:

    •   对象和类与其他对象和类有依赖关系。
    •   你的依赖关系是复杂的,或者是需要抽象。
    •   你需要构造函数、方法、或者是属性注入的功能。
    •   你需要管理对象实例的生命周期。
    •   你需要在运行的时候可以配置和改变依赖关系。
    •   你需要在web应用中缓存或者是持久化依赖关系。

      在下面的情况,你不应该使用Unity模块

    •   你的对象和类与其他的对象和类没有依赖关系。
    •   你的依赖关系很简单,不需要抽象。

      在开发的过程中使用Unity模块

      这个主题描述如何在应用开发中使用Unity模块。如何创建对象实例。

      使用Unity模块的系统需要

      最小需要如下:

    •   Microsoft Windows XP Professional,Windows Server 2003,Windows Server 2008 or Windows Vista operating System。
    •   Microsoft .NET Framework 2.0,3.0 or 3.5。
    •   Microsoft Visual Studio 2005 or 2008 development system。

      配置Unity模块

      Unity模块可以从xml配置文件中读取配置信息。默认情况下,就是应用中的app.config或者是web.config文件。你也可以从其他xml文件,或者是其他来源加载配置信息。

      在运行的时候配置容器

      1.格式化Unity配置文件

      下面的xml格式就是Unity的配置格式。

      

    <configuration> 
      <configSections> 
        <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
       </configSections> 
      <unity> ... ... 
      </unity> ... ... 
    </configuration>

       下面是一个比较完整的配置文件

      

    <?xml version="1.0" encoding="utf-8" ?> 
    <configuration> 
      <configSections> 
        <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
    Microsoft patterns & practices – Unity Application Block 1.2 – October 2008 27
    Microsoft.Practices.Unity.Configuration, =1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
     /> 
      </configSections>
       <unity> 
        <typeAliases> <!-- Lifetime manager types --> 
          <typeAlias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity" /> 
          <typeAlias alias="perThread" type="Microsoft.Practices.Unity.PerThreadLifetimeManager, Microsoft.Practices.Unity" />
           <typeAlias alias="external" type="Microsoft.Practices.Unity.ExternallyControlledLifetimeManager, Microsoft.Practices.Unity" /> <!-- User-defined type aliases --> 
          <typeAlias alias="IMyInterface" type="MyApplication.MyTypes.MyInterface, MyApplication.MyTypes" /> 
          <typeAlias alias="MyRealObject" type="MyApplication.MyTypes.MyRealObject, MyApplication.MyTypes" /> 
          <typeAlias alias="IMyService" type="MyApplication.MyTypes.MyService, MyApplication.MyTypes" /> 
          <typeAlias alias="MyDataService" type="MyApplication.MyTypes.MyDataService, MyApplication.MyTypes" /> 
          <typeAlias alias="MyCustomLifetime" type="MyApplication.MyLifetimeManager, MyApplication.MyTypes" /> 
        </typeAliases> 
        <containers> 
          <container name="containerOne"> 
            <types> <!-- Type mapping with no lifetime – defaults to "transient" --> 
              <type type="Custom.MyBaseClass" mapTo="Custom.MyConcreteClass" /> <!-- Type mapping using aliases defined above --> 
              <type type="IMyInterface" mapTo="MyRealObject" name="MyMapping" /> <!-- Lifetime managers specified using the type aliases --> 
              <type type="Custom.MyBaseClass" mapTo="Custom.MyConcreteClass"> <lifetime type="singleton" /> </type>
    28 Microsoft patterns & practices – Unity Application Block 1.2 – October 2008
    <type type="IMyInterface" mapTo="MyRealObject" name="RealObject"> <lifetime type="perThread" /> </type> <type type="IMyInterface" mapTo="MyRealObject" name="RealObject"> <lifetime type="external" /> </type> <!-- Lifetime manager specified using the full type name --> <!-- Any initialization data specified for the lifetime manager --> <!-- will be converted using the default type converter --> <type type="Custom.MyBaseClass" mapTo="Custom.MyConcreteClass"> <lifetime value="sessionKey" type="MyApplication.MyTypes.MyLifetimeManager, MyApplication.MyTypes" /> </type> <!-- Lifetime manager initialization using a custom TypeConverter --> <type type="IMyInterface" mapTo="MyRealObject" name="CustomSession"> <lifetime type="MyCustomLifetime" value="ReverseKey" typeConverter="MyApplication.MyTypes.MyTypeConverter, MyApplication.MyTypes" /> </type> <!-- Object with injection parameters defined in configuration --> <!-- Type mapping using aliases defined above --> <type type="IMyService" mapTo="MyDataService" name="DataService"> <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration"> <constructor> <param name="connectionString" parameterType="string"> <value value="AdventureWorks"/> </param> <param name="logger" parameterType="ILogger"> <dependency /> </param> </constructor> <property name="Logger" propertyType="ILogger" /> <method name="Initialize"> <param name="connectionString" parameterType="string"> <value value="contoso"/> </param> <param name="dataService" parameterType="IMyService"> <dependency /> </param> </method> </typeConfig> </type>
    Microsoft patterns & practices – Unity Application Block 1.2 – October 2008 29
    </types> <instances> <add name="MyInstance1" type="System.String" value="Some value" /> <add name="MyInstance2" type="System.DateTime" value="2008-02-05T17:50:00" /> </instances> <extensions> <add type="MyApp.MyExtensions.SpecialOne" /> </extensions> <extensionConfig> <add name="MyExtensionConfigHandler" type="MyApp.MyExtensions.SpecialOne.ConfigHandler" /> </extensionConfig>
         </container> <!-- ... more containers here ... --> </containers> 
      </unity> 
    </configuration>

      将配置信息加载到容器中

      Unity不会自动读取配置信息来创建和准备好一个容器。你需要在应用中用代码来初始化容器,你也可以用代码注册类型,类型映射,任何从文件中读取的扩展信息都可以用代码来创建。

      如果配置定义了一个未命名的容器,这个没有名字的容器就是默认的容器。你也可以给容器命名。你可以将每一个容器的配置信息加载到容器中,

      下面的代码就是初始化一个新的容器,然后加载配置文件中配置的类型,映射,和扩展定义。

      

    IUnityContainer container = new UnityContainer(); 
    UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); 
    section.Containers.Default.Configure(container);

      加载容器的时候,你也可以使用容器的名称进行加载。下面的代码就是加载了一个名为containerOne的容器。

    IUnityContainer container = new UnityContainer();
     UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); 
    section.Containers["containerOne"].Configure(container);

      

      创建一个在配置文件中定义的有继承关系嵌套的容器,你可以用CreateChildContainer方法加载每一个适当的容器信息。

      

    IUnityContainer parentContainer = new UnityContainer(); 
    IUnityContainer childContainer = parentContainer.CreateChildContainer(); 
    UnityConfigurationSection section 
    = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); 
    section.Containers["containerOne"].GetConfigCommand().Configure(parentContainer); 
    section.Containers["nestedChildContainer"].Configure(childContainer);

      你不能在配置文件中嵌套容器,在containers节中的所有container元素都是同一个级别的元素。容器嵌套是通过代码来创建,并且加载适当的容器。

      使用可替代的配置源

      如果有需要的话,你可以使用任何xml文件或者是其他源作为配置信息。例如,你可以用System.Configuration.Configuration类获取任何xml文件的配置信息,下面的代码中就是这样用的。

      

    ExeConfigurationFileMap map = new ExeConfigurationFileMap();
     map.ExeConfigFilename = "MyConfig.config"
    System.Configuration.Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
     UnityConfigurationSection section = (UnityConfigurationSection)config.GetSection("unity");
     IUnityContainer container = new UnityContainer();
     section.Containers["myContainer"].Configure(container);

      配置支持数组

      Unity支持设计时数组参数,和运行是数组参数。

      在设计的时候配置支持数组参数

      在配置文件中使用array元素作为list的代表。array元素描述了一个包含注册实例和类型映射的数组。array可以嵌套使用,包含下面三个子元素:

    •   array
    •   dependency
    •   value
      <typeAlias alias="ILoggerArray" type="Microsoft.Practices.Unity.TestSupport.ILogger[], TestSupport.Unity" /> 
       
    • <typeAlias alias="ArrayConstructor" type="Microsoft.Practices.Unity.TestSupport.ObjectArrayConstructorDependency, Tests.Unity.Configuration" /> </typeAliases> 
    • <containers> <container name="emptyArray"> <types> <type type="ArrayConstructor"> <typeConfig > <constructor> <param name="loggers" parameterType="ILoggerArray"> <array /> </param> </constructor> </typeConfig> </type>
      Microsoft patterns & practices – Unity Application Block 1.2 – October 2008 33
      </types> </container>

      下面的配置文件使用dependency子元素描述了获取指定类型的实例

      

    <typeAliases> 
      <typeAlias alias="ILogger" type="Microsoft.Practices.Unity.TestSupport.ILogger, TestSupport.Unity" / <typeAliases> 
        <container name="populatedArrayWithValues">
           <types>
             <type type="ILogger" mapTo="MockLogger" name="logger1"> <lifetime type="singleton" /> </type> 
             <type type="ILogger" mapTo="SpecialLogger" name="logger2"> <lifetime type="singleton" /> </type>
             <type type="ArrayConstructor"> 
              <typeConfig> 
                <constructor> 
                  <param name="loggers" parameterType="ILoggerArray"> <array> <dependency name="logger2"/> <dependency name="logger1"/> </array> </param> </constructor> </typeConfig> </type> 
      </types> 
    </container>

      

  • 相关阅读:
    docker底层原理
    搭建docker私有镜像仓库harbor
    docker 网络详解
    从对集合数据去重到Distinct源码分析
    学习笔记(3)centos7 下安装RabbitMQ
    学习笔记(2)centos7 下安装mysql
    学习笔记(1)centos7 下安装nginx
    2.Redis的数据类型
    1.Redis介绍以及安装
    mongoDB的安装和配置
  • 原文地址:https://www.cnblogs.com/DoNetCShap/p/2295506.html
Copyright © 2020-2023  润新知