YbSoftwareFactory 代碼生成插件【十二】:超級靈活方便的應用程序設置管理API


    通過應用程序設置可以動態存儲和檢索應用程序的屬性設置和其他信息。應用程序設置是提高應用程序靈活性的必備手段之一。通常的應用程序設置可寫人數據庫、配置文件(如Web.Config的"appSettings"配置節)和Properties.Setting(WinForm、WPF客戶端可選)等。

    本文要介紹的應用程序設置管理采用數據庫存儲的方式,實現了如下的目標:

    1、支持多種數據庫,同時預留接口,用戶可對API進行靈活擴展,支持如XML等任意形式的存儲方式。

    2、支持多應用程序、多客戶端(在C/S方式下特別有用)的應用程序設置管理,可方便地指定每個應用程序設置信息是否在各個應用程序、各個客戶端間共享。

    3、API接口豐富、調用方便,支持泛型類型的應用程序設置信息,各個客戶端可隨意定義所要保存和加載的應用程序設置信息,服務器端可集中進行管理。

    為實現一個滿足上述目標的應用程序設置API,主要采用了如下措施:

    1、使用Provider模式,可把應用程序設置存儲在多種類型的數據庫中,用戶可通過實現具體的Provider,可以實現如XML等的存儲方式。如下是API的初始化方法:

Initialize
 1  #region Initialize
 2 
 3          public  override  void Initialize( string name, System.Collections.Specialized.NameValueCollection config)
 4         {
 5              //  Validate arguments
 6               if (config ==  nullthrow  new ArgumentNullException( " config ");
 7              if ( string.IsNullOrEmpty(name)) name =  " YbSettingProvider ";
 8              if (String.IsNullOrEmpty(config[ " description "]))
 9             {
10                 config.Remove( " description ");
11                 config.Add( " description "" Yb setting provider ");
12             }
13              if (String.IsNullOrEmpty(config[ " applicationName "]))
14             {
15                 config.Remove( " applicationName ");
16                 config.Add( " applicationName "" YbApp ");
17             }
18              if (String.IsNullOrEmpty(config[ " tableName "]))
19             {
20                 config.Remove( " tableName ");
21                 config.Add( " tableName "" YbSettings ");
22             }
23 
24              //  Initialize base class
25               base.Initialize(name, config);
26 
27              //  Read connection string
28               this.ConnectionStringName = config.GetConfigValue( " connectionStringName "null);
29              if ( string.IsNullOrWhiteSpace( this.ConnectionStringName))
30                  throw  new ConfigurationErrorsException(Resources.Required_connectionStringName_attribute_not_specified);
31              this.connectionStringSetting = ConfigurationManager.ConnectionStrings[ this.ConnectionStringName];
32              if ( this.connectionStringSetting ==  null)
33                  throw  new ConfigurationErrorsException( string.Format(Resources.Format_connection_string_was_not_found,
34                                                                       this.ConnectionStringName));
35              if ( string.IsNullOrEmpty( this.connectionStringSetting.ProviderName))
36                  throw  new ConfigurationErrorsException(
37                      string.Format(
38                         Resources.Format_connection_string_does_not_have_specified_the_providerName_attribute,
39                          this.ConnectionStringName));
40 
41              // 激發設置連接字符串前的事件處理程序,主要目的是解密連接字符串
42              ConnectionStringChangingEventArgs args =
43                 RaiseConnectionStringChangingEvent(connectionStringSetting.ConnectionString);
44              if (args ==  nullthrow  new ProviderException(Resources.Connection_string_cannot_be_blank);
45              if (! this.connectionStringSetting.ConnectionString.Equals(args.ConnectionString))
46             {
47                  this.connectionStringSetting =
48                      new ConnectionStringSettings( this.ConnectionStringName, args.ConnectionString,
49                                                   this.connectionStringSetting.ProviderName);
50             }
51              if ( string.IsNullOrEmpty( this.connectionStringSetting.ConnectionString))
52                  throw  new ProviderException(Resources.Connection_string_cannot_be_blank);
53 
54              this.applicationName = config[ " applicationName "];
55 
56              this.tableName = config[ " tableName "];
57 
58              this.SiteName = config[ " siteName "];
59             SecUtility.CheckParameter( ref tableName,  truetruetrue255" tableName ");
60             SecUtility.CheckParameter( ref applicationName,  truetruefalse255" applicationName ");
61             SecUtility.CheckParameter( ref siteName,  falsefalsefalse255" siteName ");
62         }
63 
64          #endregion

    從初始化方法中可以看出,可以在config文件中配置要存儲的數據庫表名(默認為YbSettings),應用程序名(ApplicationName)和客戶端站點名(SiteName),這個配置文件可以是Web.Config,也可以是App.Config,通過指定不同的應用程序名和客戶端站點名,可以隔離不同應用程序,同一應用程序不同客戶端間的應用程序設置信息。

    2、應用程序設置類可以定義任意類型的屬性,非常靈活和方便,應用程序設置的保存和加載主要通過反射方式實現,具體的應用程序設置類可以像下面一樣:

public  class ClientSetting : BaseSettings
    {
         public  override  bool AsShared
        {
             get {  return  false; }
        }

        [DisplayName( " 允許注冊 ")]
        [System.ComponentModel.Description( " True:允許注冊,False:不允許注冊 ")]
        [DefaultValue( true)]
         public  bool AllowRegister {  getset; }

         public  int MaxNumber {  getset; }

        [DefaultValue(10d)]
         public  double MaxWidth {  getset; }

        [DefaultValue(20d)]
         public  double MaxHeight {  getset; }
    }

    在上述的應用程序設置類的定義中,可以對每個屬性設置“DisplayName”特性和“Description”特性,這些信息將在反射時自動保存至數據庫中,主要目的是方便后台對單個屬性項進行管理;同時還可以設置“DefaultValue”特性,這樣如果數據庫中不存在該設置項將自動加載為指定的默認值,是不是非常方便和靈活!!!也可定義AsShared屬性指明該應用程序設置類的信息是否在同一應用程序多個客戶端或站點間進行共享。

    具體的應用程序設置加載就方便多了,只需如下一條語句就可加載指定的類中定義的多個屬性對應的設置信息:

    SettingApi.LoadSettings<ClientSetting>();

    具體的保存也非常方便,也僅需一條語句即可:

    SettingApi.SaveSettings(clientSetting);

    具體到實現原理上,應用程序設置API將把上述設置信息類的每個屬性及其值按規則單獨保存至數據庫的一條記錄中,具體保存的實現方法使用了反射,代碼如下:

SaveSettings
 1  public  static  void SaveSettings<T>(T settings)  where T : BaseSettings,  new()
 2         {
 3             Initialize();
 4 
 5              string siteName =  string.Empty;
 6              if (!settings.AsShared)
 7                 siteName = SiteName;
 8              foreach ( var prop  in  typeof(T).GetProperties())
 9             {
10                  //  get properties we can read and write to
11                   if (!prop.CanRead || !prop.CanWrite)
12                      continue;
13 
14                  if (!CommonHelper.GetCustomTypeConverter(prop.PropertyType).CanConvertFrom( typeof( string)))
15                      continue;
16 
17                  string key =  typeof(T).Name +  " . " + prop.Name;
18 
19                  string displayName = prop.Name;
20                  var displayNameAttrs = prop.GetCustomAttributes( typeof(DisplayNameAttribute),  false);
21                  if (displayNameAttrs.Length >  0)
22                 {
23                     DisplayNameAttribute attr = displayNameAttrs[ 0as DisplayNameAttribute;
24                      if (attr !=  null && ! string.IsNullOrWhiteSpace(attr.DisplayName))
25                         displayName = attr.DisplayName;
26                 }
27                  string description =  string.Empty;
28                  var desAttrs = prop.GetCustomAttributes( typeof(DescriptionAttribute),  false);
29                  if (desAttrs.Length >  0)
30                 {
31                     DescriptionAttribute attr = desAttrs[ 0as DescriptionAttribute;
32                      if (attr !=  null && ! string.IsNullOrWhiteSpace(attr.Description))
33                         description = attr.Description;
34                 }
35 
36                 dynamic value = prop.GetValue(settings,  null);
37                  if (value !=  null)
38                     SetSetting(key, value, displayName: displayName, description: description, siteName: siteName);
39                  else
40                     SetSetting(key,  "", displayName, description, siteName);
41             }
42         }

    本應用程序設置在配置文件中的配置方式如下:

   < yb.data >
     < setting  defaultProvider ="YbSettingProvider" >
       < providers >
         < add  name ="YbSettingProvider"  connectionStringName ="AdMisDb"  applicationName ="YbApplication"  siteName ="YbTestSite"  type ="Yb.Data.Provider.YbSettingProvider,Yb.Data.Provider" ></ add >
       </ providers >
     </ setting >
   </ yb.data >

    附最新發布 YbRapidSolution for MVC Demo 地址:http://mvcdemo.yellbuy.com/

    YbSoftwareFactory 2.4正式發布,提供下載地址:http://download.yellbuy.com/ybsoftwarefactory/Yb.SoftwareFactory_V2_Release.rar 

    下一章將我們將討論 Web API 的安全


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM