使用 Unity(二):配置 Unity 、读取配置信息和获取对象

来源:互联网 发布:全方位安全软件 编辑:程序博客网 时间:2024/06/06 19:53

和 Enterprise Library 的其他应用程序块一样,Unity 的行为也可以通过配置来指定。

Unity 应用程序块可以从 XML 配置文件中读取配置信息。配置文件可以是 Windows Forms 应用程序的 App.config 或者 ASP.NET 应用程序的 Web.config。当然,也可以从任何其他 XML 格式的文件或者其他数据源中加载配置信息。

在本文中,将和大家一起来学习 Unity 配置文件的格式、配置的读取、通过示例说明实例的获取。

1. Unity 配置文件的格式

Unity 配置文件看起来像下面这样:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration" />
  </configSections>
  <unity>
    <containers  >
      <container name="containerOne" >
        <types>
          <type type="System.Data.IDbConnection,System.Data"
                 mapTo="DorianDeng.UnityConfigurationExe.MyDefaultConnection,DorianDeng.UnityConfigurationExe" />
          <type name="baseMap" type="System.Data.Common.DbConnection,System.Data"
                 mapTo="DorianDeng.UnityConfigurationExe.MyDbConnection,DorianDeng.UnityConfigurationExe" lifetime="Transient" />
          <type name="interfaceSingleton" type="System.Data.IDbConnection,System.Data"
                 mapTo="DorianDeng.UnityConfigurationExe.MyDbConnection,DorianDeng.UnityConfigurationExe" lifetime="Singleton"/>
        </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>
      </container>
    </containers>
  </unity>
</configuration>

 1.1 配置节

Unity  的配置节的名称为”unity",节处理程序的类型为 Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,它包含在程序集 Microsoft.Practices.Unity.Configuration 中。

1.2 unity 的子元素

unity 的子元素包含了一个 containers 元素,此元素有一个必须的属性 Default (此属性在目前的版本中不可用),它用于指定在不指定容器获取容器的配置时的默认容器。

containers 元素可以包含若干个 container 元素。container 元素就是每个容器的配置,它有一个可选的 name 属性,用于指定容器的名称。

container 元素有下列子元素:

  • types 元素
  • instances 元素
  • extensions 元素

注意:不能嵌套定义容器,即 container 元素不能嵌套。

1.3 types 元素

types 元素是 container 元素的子元素之一。包含任意数量的 type元素,用以添加类型注册。

下面的表格列出了用于 types 的 type元素的属性。

属性描述name在注册此类型时使用的名称。此属性是可选的,如果不指定此属性,所在的 add 元素即为默认的类型映射。type容器中配置的源类型。如果这是映射注册,这就是映射的起始对象的类型;如果这是单件注册,这就是对象的类型。此属性是必须的。mapTo类型映射的目标类型。如果这是映射注册,这就是映射的目标对象的类型。此属性是可选的。lifetime设置用于给定的类型和名称的生命周期。是一个来自 LifetimeStyle 枚举的值。有效的值是 Transient(默认),它导致了容器每次都创建一个新的实例;以及 Singleton,它使容器为每个请求返回同一实例。如果在配置一个单件时同时指定了 type 和 mapto 属性,SetSingleton 方法将返回指定在 mapTo 属性中的类型。如果 mapTo 属性没有指定值,SetSingleton 方法将返回指定在 type 属性中的类型。

在此的单件(Singleton)即是人们常说的单件模式中的单件。SetSingleton 方法是容器提供的用于获取单件的方法。容器会根据 lifetime 属性来决定生成实例的方式。

 1.4 instances 子元素

instances 元素保持了用于此容器的已有对象实例的列表。这些对象(包括简单类型如数据库连接字符串)被用容器的 RegisterInstance 方法进行注册。instances 元素包含了一系列添加单个实例的 add 元素。

下面的表格列出了用于用于实例的 add 元素的属性。

属性描述name注册此实例时使用的名称。此属性是可选的。type此实例的类型。此属性是可选的。如果忽略,假定的类型是 System.String。value用于初始化实例的值。此属性是必须的。typeConverter用以转换提供的值到实例的匹配类型的类型转换器。如果没有指定,将使用指定类型的默认转换器。此属性是可选的。

 1.5 extensions 元素

extensions 元素保持了添加注册到 Unity 容器的扩展的列表。extensions 包含一系列添加单个扩展的 add 元素。

下面的表格列出了用于用于扩展的 add 元素的属性。

属性描述type添加到容器的扩展的类型。此属性是必须的。

 2 示例

我们现在仅对 types 子元素和 instances 子元素进行学习,extensions 子元素在随后单独进行。

在示例中,我们分别定义了二个继承自 System.Data.Common.DbConnection 类的 MyDefaultConnection 和 MyDbConnection,虽然这二个类并不能实现真正的连接,但在此做为示例已足够了。

2.1 读取配置创建容器

如文章开头配置文件中,我们定义了一个命名的窗口 "containerOne",因此,我们可以用下列代码来读取配置并用配置来初始化容器。

注意:Unity 应用程序块不会自动的读取配置信息,或者创建和准备容器。

        /// <summary>
        /// 创建容器。
        /// </summary>
        /// <returns></returns>
        private static IUnityContainer CreateContainer() {
            IUnityContainer container = new UnityContainer();
            UnityConfigurationSection section
              = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
            section.Containers["containerOne"].GetConfigCommand().Configure(container);
            return container;
        }

 在上面的代码中,我们用第一行来实例化一个容器,第二行使用 .NET 的 ConfigurationManager 类来读取配置节,第三行初始化容器。

如果我们定义了一个默认的容器(未命名的容器),那么,我们就可以用下列的代码来初始化容器:

section.Containers.Default.GetConfigCommand().Configure(container);

 嵌套的容器为管理依赖注入和对象生命周期提供了有用的功能,这在以后的文章中会详细讨论。

虽然,在配置文件中我们并不能嵌套的定义容器,但可以使用代码来创建并初始化容器,如下面的代码所示:

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

 2.2 创建默认实例

默认实例就是通过未命名的类型映射来注册的实例,如示例配置文件中的第一个 type。那么,我们就可以使用如下代码来获取并使用实例。(完整的代码请参见源文件。)

        private static void DefaultMap() {
            IUnityContainer container = CreateContainer();
            IDbConnection connection = container.Get<IDbConnection>();
            connection.Open();
            connection.Close();
        }
 

 执行的效果如下图如示:

 

2.3 根据键和类型来获取对象

对于配置文件中的第二个 type 元素,我们可以用以下语句来获取对象:

            DbConnection connection = container.Get<DbConnection>("baseMap");

 2.4 获取单件对象

对于单件(Singleton)的相关概念,大家可以参考设计模式中的模式,在此仅讨论如何用 Unity 来获取单件对象。

在配置文件中的第三个 type 就是单件对象的配置(lifetime="Singleton")。通过下面的代码,我们可以看到 Unity 是否实现了单件对象的获取。

        /// <summary>
        /// 获取单件对象。
        /// </summary>
        private static void SingletonMap() {
            IUnityContainer container = CreateContainer();

            IDbConnection connection = container.Get<IDbConnection>("interfaceSingleton");
            connection.ConnectionString = "server=10.99.123.22,...";
            Console.WriteLine(connection.ConnectionString);

            IDbConnection secodeConnection = container.Get<IDbConnection>("interfaceSingleton");
            secodeConnection.ConnectionString = "server=192.168.0.2...";

            Console.WriteLine(connection.ConnectionString);
        }
 

 效果如下图所示:

由此我们可以看到,虽然获取了二个对象,但事实上通过配置指定, Unity 容器为我们管理了一个单件对象,二个变量实质指向相同的对象引用。

2.5 instances 实例

在配置文件中的 instances 元素的作用相当于使用 Unity 的 RegisterSingleton 方法来注册已有的单件对象。因此,可以使用如下代码来获取配置文件中的定义的二个实例:

        /// <summary>
        /// instances 元素的示例。
        /// </summary>
        private static void InstancesExample() {
            IUnityContainer container = CreateContainer();

            string instances1 = container.Get<string>("MyInstance1");
            Console.WriteLine(instances1);

            DateTime instances2 = container.Get<DateTime>("MyInstance2");
            Console.WriteLine(instances2);

        }
 

 可以看出,这与前几个示例的获取代码没有什么区别,所以无论使用哪种方式进行配置,对客户代码来说都是一样的。

3 结束语

因为目前 Unity 还仅是 CTP 版本,所以代码、文档都些 bug 的存在,所以文章的内容可能会与文档的内容不一致,但这是目前正确的使用方法。

示例中的源代码,请在这里下载。

关于 Unity 的方法的详细使用方法,请继续关注我的理想&美人。

0 0
原创粉丝点击