zoukankan      html  css  js  c++  java
  • ASP.NET MVC 学习笔记-7.自定义配置信息(后续)

    自定义配置信息的高级应用

    通过上篇博文对简单的自定义配置信息的学习,使得更加灵活的控制系统配置信息。实际项目中,这种配置的灵活度往往无法满足项目的灵活度和扩展性。

    比如,一个配置信息有三部分组成,而每部分中有包括一些配置信息。仅仅使用简单的自定义配置无法满足,因此,需要提供更多的自定义配置方法来灵活实现。

    针对配置信息中包括配置列表和配置项的要求,主要使用.Net Framework中的以下两个类来实现:

    ConfigurationElement:配置文件中的一个配置项

    ConfigurationElementCollection:配置文件中的一个配置项集合

    ConfigurationSection:配置文件中的一个配置节信息。

    使用下面的表格能够更好说明三者之间的关系:

    ConfigurationSection

    1:N

    ConfigurationElementCollection

    1:N

    ConfigurationElement <add …/>

    ConfigurationElement <add …/>

    ConfigurationElement <add …/>

    针对以上知识点,使用一个项目实例逐渐展开。

    项目需求:

    库位管理系统需要实现仓库的全方位展示,设计多种数据(SQLserver、Oracle、MySQL等),每个数据库连接字符串的加密方式存在无法统一的情况。

    配置文件的规划:

     针对以上需求,对数据库配置文件信息的规划为:

    DBConnectionConfiguration(ConfigurationSection)

    ConnectionStrings(ConfigurationElementCollection)

    ConnectionString1(ConfigurationElement)

    name

    description

    connectionString

    providerName

    connectionDecryptName

    ConnectionString2(ConfigurationElement)

    name

    description

    connectionString

    providerName

    connectionDecryptName

    DataProviders(ConfigurationElementCollection)

    DataProvider1(ConfigurationElement)

    name

    description

    type

    DataProvider2(ConfigurationElement)

    name

    description

    type

    ConnectionDecrypts(ConfigurationElementCollection)

    ConnectionDecrypt(ConfigurationElement)

    name

    description

    type

    ConnectionDecrypt(ConfigurationElement)

    name

    description

    type

    配置信息实体的定义:

    针对以上配置信息,先对配置信息对应的实体进行设计:

    1. DBConnectionConfiguration

    它作为配置文件中的一个配置节存在,配置节名称定义为TT.connectionManager,需要继承自ConfigurationSection类,同时,它还需要定义三个属性,分别是ConnectionStrings、DataProviders、ConnectionDecrypts,这三个属性都是列表信息,因此是ConfigurationElementCollection的自定义子类。

     1     /// <summary>
     2     /// 数据库连接配置信息
     3     /// </summary>
     4     public class DBConnectionConfiguration : ConfigurationSection
     5     {
     6         private const string SECION_NAME = "TT.connectionManager";
     7 
     8         /// <summary>
     9         /// 获取数据库连接配置信息
    10         /// </summary>
    11         public static DBConnectionConfiguration GetConfig()
    12         {
    13             var config = ConfigurationManager.GetSection(SECION_NAME) as DBConnectionConfiguration;
    14             return config;
    15         }
    16 
    17         /// <summary>
    18         /// 数据库连接字符串配置集合
    19         /// </summary>
    20         [ConfigurationProperty("connectionStrings")]
    21         public ConnectionStringCollection ConnectionStrings
    22         {
    23             get
    24             {
    25                 return (ConnectionStringCollection)base["connectionStrings"];
    26             }
    27         }
    28 
    29         /// <summary>
    30         /// DataProvider配置集合
    31         /// </summary>
    32         [ConfigurationProperty("dataProviders", IsRequired = true)]
    33         public DataProviderCollection DataProviders
    34         {
    35             get
    36             {
    37                 return (DataProviderCollection)base["dataProviders"];
    38             }
    39         }
    40 
    41         /// <summary>
    42         /// 连接字符串加密方式
    43         /// </summary>
    44         [ConfigurationProperty("connectionDecrypts", IsRequired = false)]
    45         public ConnectionDecryptCollection ConnectionDecrypts
    46         {
    47             get
    48             {
    49                 return (ConnectionDecryptCollection)base["connectionDecrypts"];
    50             }
    51         }
    52     }

    2. ConnectionString

    由于定义ConfigurationElementCollection的子类时,需要使用泛型方式,定义其包含的配置项的类型,因此,先定义配置项的实体。

    由于,三个不同的配置项派生类都需要在配置信息中定义名称和描述信息来标识配置项信息,因此,提取出配置项基类,使用的配置项实体都继承自该基类,不同的配置信息在各自类中进行自定义。

     1     /// <summary>
     2     /// 以名字为键值的配置项
     3     /// </summary>
     4     public class NamedConfigurationElement : ConfigurationElement
     5     {
     6         /// <summary>
     7         /// 名称
     8         /// </summary>
     9         [ConfigurationProperty("name", IsRequired = true, IsKey = true)]
    10         public virtual string Name
    11         {
    12             get
    13             {
    14                 return (string)this["name"];
    15             }
    16         }
    17 
    18         /// <summary>
    19         /// 描述
    20         /// </summary>
    21         [ConfigurationProperty("description", DefaultValue = "")]
    22         public virtual string Description
    23         {
    24             get
    25             {
    26                 return (string)this["description"];
    27             }
    28         }
    29     }

    以ConnectionStringElement为例,该实体定义三个属性信息:数据库连接字符串信息、数据库访问提供者、连接加密信息名称,其中连接加密名称填写时,使用ConnectionDecryptCollection中的定义解密类的类型信息进行反射实例化进行解密,不填写时则直接使用连接字符串信息。

     1 /// <summary>
     2 /// 连接字符串配置项
     3 /// </summary>
     4 public class ConnectionStringElement:NamedConfigurationElement
     5 {
     6     /// <summary>
     7     /// 连接字符串
     8     /// </summary>
     9     private string _connectionString = "";
    10 
    11     /// <summary>
    12     /// 连接字符串
    13     /// </summary>
    14     [ConfigurationProperty("connectionString")]
    15     public string ConnectionString
    16     {
    17         get
    18         {
    19             if (!string.IsNullOrWhiteSpace(_connectionString))
    20                 return _connectionString;
    21             var decryptName = ConnectionDecryptName;
    22             if (string.IsNullOrWhiteSpace(decryptName))
    23                 _connectionString = (string)base["connectionString"];
    24             else
    25             {
    26                 DBConnectionConfiguration config = DBConnectionConfiguration.GetConfig();
    27                 var decrytType = config.ConnectionDecrypts[decryptName].Type;
    28                 IConnectionDecrypt cb = ReflectionHelper.CreateInstance(decrytType) as IConnectionDecrypt;
    29                 _connectionString = cb.Decrypt((string)base["connectionString"]);
    30             }
    31             return _connectionString;
    32         }
    33     }
    34 
    35     /// <summary>
    36     /// DataProvider名称
    37     /// </summary>
    38     [ConfigurationProperty("providerName")]
    39     public string ProviderName
    40     {
    41         get
    42         {
    43             return (string)base["providerName"];
    44         }
    45     }
    46 
    47 
    48     /// <summary>
    49     /// 连接字符串加密方法名称
    50     /// </summary>
    51     [ConfigurationProperty("connectionDecryptName", DefaultValue = "", IsRequired = false)]
    52     public string ConnectionDecryptName
    53     {
    54         get
    55         {
    56             return (string)base["connectionDecryptName"];
    57         }
    58     }
    59 }
     1     /// <summary>
     2     /// DataProvider配置项
     3     /// </summary>
     4     public class DataProviderElement: NamedConfigurationElement
     5     {
     6         /// <summary>
     7         /// DataProvider类型信息
     8         /// </summary>
     9         [ConfigurationProperty("type")]
    10         public string Type
    11         {
    12             get
    13             {
    14                 return (string)base["type"];
    15             }
    16         }
    17 }
     1     /// <summary>
     2     /// 字符串加密方式配置项
     3     /// </summary>
     4     public class ConnectionDecryptElement:NamedConfigurationElement
     5     {
     6         /// <summary>
     7         /// 字符串加密方式类型信息
     8         /// </summary>
     9         [ConfigurationProperty("type")]
    10         public string Type
    11         {
    12             get
    13             {
    14                 return (string)base["type"];
    15             }
    16         }
    17     }

    3. ConnectionStrings类

    ConnectionStrings、DataProviders、ConnectionDecrypts三个配置列表实体,都会使用到使用配置项的名称获取对应的配置信息,因此需要将公共方法提取出来基类。

     1 public abstract class NamedConfigurationElementCollection<T> : ConfigurationElementCollection
     2 
     3     where T : NamedConfigurationElement, new()
     4 
     5 {
     6  
     7     /// <summary>
     8     /// 按照名称获取指定的配置元素
     9     /// </summary>
    10     /// <param name="name">名称</param>
    11     /// <returns>配置元素</returns>
    12     public new T this[string name] { get { return (T)BaseGet(name); } }
    13 
    14 
    15     /// <summary>
    16     /// 是否包含指定的配置元素
    17     /// </summary>
    18     /// <param name="name">配置元素名称</param>
    19     /// <returns>是否包含</returns>
    20     public bool ContainsKey(string name) { return BaseGet(name) != null; }
    21 
    22     /// <summary>
    23     /// 添加元素
    24     /// </summary>
    25     /// <param name="obj"></param>
    26     public virtual void Add(T obj)
    27     {
    28         BaseAdd(obj);
    29     }
    30 
    31     /// <summary>
    32     /// 得到元素的Key值
    33     /// </summary>
    34     /// <param name="element">配置元素</param>
    35     /// <returns>配置元素所对应的配置元素</returns>
    36     protected override object GetElementKey(ConfigurationElement element) { return ((T)element).Name; }
    37  
    38     /// <summary>
    39     /// 生成新的配置元素实例
    40     /// </summary>
    41     /// <returns>配置元素实例</returns>
    42     protected override ConfigurationElement CreateNewElement() { return new T(); }
    43 }

    定义基类后,ConnectionStrings、DataProviders、ConnectionDecrypts三个配置列表实体只需要继承该基类,不需要任何实现。

     1 public class ConnectionStringCollection: NamedConfigurationElementCollection<ConnectionStringElement>
     2 {
     3 
     4        
     5 
     6 }
     7 
     8 public class DataProviderCollection: NamedConfigurationElementCollection<DataProviderElement>
     9 {
    10 
    11 }
    12 
    13 public class ConnectionDecryptCollection: NamedConfigurationElementCollection<ConnectionDecryptElement>
    14 {
    15 
    16 
    17 }

    通过以上配置实体类的定义,就可以使用以下方式获取到数据库配置信息:

    DBConnectionConfiguration settings = DBConnectionConfiguration.GetConfig();

    然后,根据数据库连接的名称获取到对应的信息,比如:

    var connectionString = settings.ConnectionStrings[dbName].ConnectionString;

    这里的DBName就是connectString配置项中的name信息。

  • 相关阅读:
    springboot 入门
    json-lib 的 maven dependency 引入及Jar包下载
    DataGridView 使用技巧精华
    SqlServer无备份下误删数据恢复
    Reflector 已经out了,试试ILSpy
    C# 反射,动态编译
    windows8和windows server2012不联网安装.net 3.5(包括2.0和3.0)
    如何附加被分离的质疑数据库? [转]
    easyui validatebox 验证类型
    所见即所得:七大无需编程的DIY开发工具
  • 原文地址:https://www.cnblogs.com/DreamOfLife/p/9056928.html
Copyright © 2011-2022 走看看