• EnterpriseLibrary的DAAB如何灵活配置数据库的笔记


    hi,all,
    项目中常常用到EnterpriseLIbrary2006Jan库中的DAAB,所以经常需要用PPT给员工说明一下DAAB配置文件中如何配置数据库连接字符串的。下面就是一些简单的文字描述:
     
    第一小节:
    什么是节处理器 (Section Handlers)

    在配置文件里除了 常见的system.net、system.data等节点之外, 还可以自已写 XML 格式的配置元素,这些元素叫做节(Section)。当然,如果你自己写一堆复杂的 XML 格式的标签,.NET 自身是不知道如何解析的,因此这里就需要你在指定节的同时,告诉 .NET 如何处理它们,也就是定义“节处理器”(Section Handlers)。

    每一个自定义的节,都需要在 configSections 下面定义它们的节处理器。先来看一个例子:

    <?xml version="1.0" encoding="utf-8" ?>

     <configuration>

     <configSections>

           <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings,Microsoft.Practices.EnterpriseLibrary.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />

      </configSections>

     

    这就是定义说,如果发现在配置文件有“dataConfiguration”节点,那么就应该用assembly“Microsoft.Practices.EnterpriseLibrary.Data”的“Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings”类来处理。

     

    第二小节,

    为什么它能处理?

    我们来看dataConfiguration节点中都定义了什么:

    <dataConfiguration defaultDatabase="USP_Authentication">

     <providerMappings>

      <add databaseType="Microsoft.Practices.EnterpriseLibrary.Data.GenericDatabase, Microsoft.Practices.EnterpriseLibrary.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" name="Data.Usp.mssql" />

      </providerMappings>

      </dataConfiguration>

    它包含了两个东西:

    属性:defaultDatabase

    和节点:providerMappings

    ,如果DAAB写程序读取配置,需要处理这两个东西。

     

    接下来我们打开Enterprise library 2006.Jan的Data solution,看看Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings是怎么定义的。

     /// <remarks>
     /// <para>The class maps to the <c>databaseSettings</c> element in configuration.</para>
     /// </remarks>
     public class DatabaseSettings : SerializableConfigurationSection


    Enterprise Library 的配置框架建立在 System.Configuration 的基础之上,而且工作方式也与其非常相似。应用程序块的配置节派生自 Microsoft.Practices.EnterpriseLibrary.Common.Configuration.SerializableConfigurationSection,而不是直接从 System.Configuration.ConfigurationSection 派生。
    SerializableConfigurationSection 也是Microsoft.Practices.EnterpriseLibrary.Common.Configuration下的类,是从ConfigurationSection, IXmlSerializable类继承可以看出是对ConfigurationSection的扩展,而每个EntLib应用程序块的配置节点都必须继承自此类,此类主要包括了对XML文件节点的操作方法。

    {
      private const string defaultDatabaseProperty = "defaultDatabase";
      private const string dbProviderMappingsProperty = "providerMappings";

      /// <summary>
      /// The name of the data configuration section.
      /// </summary>
      public const string SectionName = "dataConfiguration";

    最重要的代码是:

    public static DatabaseSettings GetDatabaseSettings(IConfigurationSource configurationSource)
      {
       return (DatabaseSettings)configurationSource.GetSection(SectionName);
      }

    它的意义就是,从配置文件中指定dataConfiguration名的节点树把配置读取到ConfigurationSection对象中。

    之后就可以:

    对于属性,它这么处理:

    [ConfigurationProperty(defaultDatabaseProperty, IsRequired = false)]
      public string DefaultDatabase
      {
       get
       {
        return (string)this[defaultDatabaseProperty];
       }
       set
       {
        this[defaultDatabaseProperty] = value;
       }
      }

    对于节点,它这么处理:

    [ConfigurationProperty(dbProviderMappingsProperty, IsRequired = false)]
      public NamedElementCollection<DbProviderMapping> ProviderMappings
      {
       get
       {
        return (NamedElementCollection<DbProviderMapping>)base[dbProviderMappingsProperty];
       }
      }

    示意如下:

    第三步,

    配置节点详解

    我们在配置文件中用

    <system.data>
        <DbProviderFactories>
          <add
        name="Sql Server 2005"
        invariant="Data.Usp.mssql"
        description="An alias for the SqlProvider"
        type="System.Data.SqlClient.SqlClientFactory, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        </DbProviderFactories>
      </system.data>

    设定了database的provider,在这里可以指定很多种不同的provider,比如:

    <system.data>
        <DbProviderFactories>
          <add name="my Generic Database" invariant="MyOleDBDatabase" description="An alias for the OleDBProvider" type="System.Data.OleDb.OleDbFactory, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        </DbProviderFactories>
      </system.data>

    此时要用自己定义的provider,就可以这么定义连接字符串:

    <connectionStrings>
        <add name="MyTestConnectionString" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\My2005Codes\TestCode\AccessDB.mdb;"
          providerName="MyOleDBDatabase" />
      </connectionStrings>

    当然,也可以不用在这里指定,而是后面连接字符串配置节点中直接指定已有的provider。

    我们现在的连接字符串配置是:

    <connectionStrings>
        <add
        name="Authentication"
        providerName="System.Data.SqlClient"
        connectionString="Server=11.168.1.22;database=DB_Authentication;UID=usp;PWD=de;" />

        <add
        name="Log"
        providerName="Data.Usp.mssql"
        connectionString="Server=11.168.1.22;DataBase=DB_Log;UID=logger;PWD=de;" />
       
      </connectionStrings>

    那么,实际上这个“System.Data.SqlClient”就是系统约定的provider名,用我们自定义的“Data.Usp.mssql”也可以达到同样的效果。

    第四步,

    当我们调用

    DatabaseFactory.CreateDatabase("Authentication");

    时,实际上就是命令DAAB用
    <add
        name="Authentication"
        providerName="System.Data.SqlClient"
        connectionString="Server=11.168.1.22;database=DB_Authentication;UID=usp;PWD=de;" />

    所指定的连接字符串去连数据库。

    辅助参考蝈蝈俊的blog:

    DatabaseFactory.CreateDatabase 方法创建数据库实例的 逻辑过程

    简单看一下  DatabaseFactory.CreateDatabase 方法 是根据啥关系,来判断应该创建的是 Database 抽象类的那个子类。

    分析代码可知,这里的判断分三步:
    主要代码看 DatabaseCustomFactory.cs 文件的
    public object CreateObject(IBuilderContext context, string name, IConfigurationSource configurationSource, ConfigurationReflectionCache reflectionCache)方法。

    第一步:
    在链接字符串中,我们可以根据链接字符串的 name 获得 链接字符串的 providerName 。

    第二步:
    如果 我们设置了 providerName 的任何 影射关系, 则自动获得 这个映射的 DbProviderMapping ;
    如果这个数据库访问者 没有被设置任何影射关系, 则 系统自动在默认提供的 SqlDatabase、 OracleDatabase 中匹配。
    如果上述都没匹配出结果, 则 返回 GenericDatabase 。

    上述逻辑在 DatabaseConfigurationView.cs 文件中可以看到代码:


    public DbProviderMapping GetProviderMapping(string name, string dbProviderName)
    {
     DatabaseSettings settings = this.DatabaseSettings;
     if (settings != null)
     {
      DbProviderMapping existingMapping = settings.ProviderMappings.Get(dbProviderName);
      if (existingMapping != null)
      {
       return existingMapping;
      }
     }

     DbProviderMapping defaultMapping = this.GetDefaultMapping(name, dbProviderName);
     if (defaultMapping != null)
     {
      return defaultMapping;
     }

     return this.GetGenericMapping();
    }

    第三步
    根据 DbProviderMapping 生成 Database 抽象类的实例。

    根据上述逻辑描述,我们就可以理解如下一个数据库的配置文件了。

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <configSections>
        <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </configSections>

      <dataConfiguration defaultDatabase="MyTestConnectionString">
        <providerMappings>
          <add databaseType="Microsoft.Practices.EnterpriseLibrary.Data.GenericDatabase, Microsoft.Practices.EnterpriseLibrary.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
            name="GenericDatabase" />
          <add databaseType="Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase, Microsoft.Practices.EnterpriseLibrary.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
            name="System.Data.SqlClient" />
        </providerMappings>
      </dataConfiguration>

      <connectionStrings>
        <add name="MyTestConnectionString" connectionString="server=(local)\SQLEXPRESS;database=EntLibQuickStarts;Integrated Security=true;"
          providerName="GenericDatabase" />
      </connectionStrings>

      <system.data>
        <DbProviderFactories>
          <add name="my Generic Database" invariant="GenericDatabase" description="An alias for the SqlProvider" type="System.Data.SqlClient.SqlClientFactory, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        </DbProviderFactories>
      </system.data>

    </configuration>

    这个数据库配置文件生成的  Database dbSvc = DatabaseFactory.CreateDatabase();
    dbSvc 必然是 Microsoft.Practices.EnterpriseLibrary.Data.GenericDatabase 类型的。

    注意: 
    system.data 数据节 的 DbProviderFactories 配置节 是给配置文件中 connectionStrings 节的 providerName 对应用的。
    而 dataConfiguration 配置节的 providerMappings 是给 生成 的 是那一个 Database 抽象类的那一个实例用的。

    参考资料:

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/entlibjan2006_dataaccessappblock.asp
    http://blogs.msdn.com/tomholl/archive/2005/09/14/466298.aspx
    http://www.dotnetslackers.com/VB_NET/re-9165_DAAB_in_Enterprise_Library_for_NET_2_0.aspx

    郑昀 笔记  200703

     

    推荐阅读:

    从美国单身男女的分布图说起--纵论视觉化叙述 (3-1 20:54)

    [职场生存]细节和感觉[]:感觉 (1-28 23:16)

    [职场生存]细节和感觉[]:细节包括哪些部分? (1-28 23:15)

    [职场生存]细节和感觉[] (1-25 21:09)

    郑昀邀请C#架构师加盟易通无线[工作地点-北京财智国际大厦] (3-5 14:58)

  • 相关阅读:
    YUM软件管理
    RPM软件包管理
    Linux系统启动详解
    Linux命令行文本处理工具
    Linux多命令协作:管道及重定向
    Linux网络基础配置
    网络基础
    Linux扩展权限
    Linux权限机制
    Linux用户基础
  • 原文地址:https://www.cnblogs.com/zhengyun_ustc/p/entlibdaabconfig.html
Copyright © 2020-2023  润新知