首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 設計模式實戰:Provider 模式(提供者模式)完整實現與配置驅動

     編輯:關於C#

模式意圖

將抽象契約與具體實現分離,通過配置文件動態載入提供者,實現儲存介質(SQL Server / XML / 其他)的熱插拔。

領域模型

public class MessageModel {
    public string Message { get; set; }
    public DateTime PublishTime { get; set; }
    public MessageModel(string msg, DateTime pt) { Message = msg; PublishTime = pt; }
}

抽象提供者基類

public abstract class MessageProvider : ProviderBase {
    public abstract bool Insert(MessageModel m);
    public abstract List<MessageModel> Get();
}

兩種具體實現

// SQL 版
public class SqlMessageProvider : MessageProvider {
    private string _connStr;
    public override bool Insert(MessageModel m) { /* ADO.NET 寫入 */ return true; }
    public override List<MessageModel> Get() { /* 查詢 */ return list; }
    public override void Initialize(string name, NameValueCollection config) {
        base.Initialize(name, config);
        _connStr = ConfigurationManager.ConnectionStrings[config["connectionStringName"]].ConnectionString;
    }
}

// XML 版(結構相同,僅存取邏輯不同)
public class XmlMessageProvider : MessageProvider { ... }

配置區段與集合

public class MessageProviderCollection : ProviderCollection {
    public override void Add(ProviderBase p) {
        if (!(p is MessageProvider)) throw new ArgumentException("必須為 MessageProvider");
        base.Add(p);
    }
}

public class MessageProviderConfigurationSection : ConfigurationSection {
    [ConfigurationProperty("defaultProvider")] public string DefaultProvider { get; set; }
    [ConfigurationProperty("providers")] public ProviderSettingsCollection Providers { get; }
    // Property 集合初始化...
}

門面類別:統一對外入口

public class Message {
    private static MessageProvider _provider;
    private static MessageProviderCollection _providers;
    private static bool _initialized;

    static Message() => Initialize();

    private static void Initialize() {
        var section = (MessageProviderConfigurationSection)ConfigurationManager.GetSection("MessageProvider");
        _providers = new MessageProviderCollection();
        ProvidersHelper.InstantiateProviders(section.Providers, _providers, typeof(MessageProvider));
        _provider = _providers[section.DefaultProvider] as MessageProvider;
    }

    public static bool Insert(MessageModel m) => _provider.Insert(m);
    public static List<MessageModel> Get() => _provider.Get();
}

Web.config 範例

<configSections>
  <section name="MessageProvider" type="Pattern.Provider.MessageProviderConfigurationSection, Pattern.Provider" />
</configSections>
<MessageProvider defaultProvider="SqlMessageProvider">
  <providers>
    <add name="SqlMessageProvider" type="Pattern.Provider.SqlMessageProvider, Pattern.Provider" connectionStringName="SqlConnection" />
    <add name="XmlMessageProvider" type="Pattern.Provider.XmlMessageProvider, Pattern.Provider" connectionStringName="XmlConnection" />
  </providers>
</MessageProvider>
<connectionStrings>
  <add name="SqlConnection" connectionString="server=.;database=db;uid=sa;pwd=sa" />
  <add name="XmlConnection" connectionString="XmlPath" />
</connectionStrings>

測試與結果

protected void Page_Load(object sender, EventArgs e) {
    Response.Write(Message.Insert(new MessageModel("測試", DateTime.Now)));
    Response.Write("<br/>");
    Response.Write(Message.Get()[0].Message + " " + Message.Get()[0].PublishTime);
}
// 輸出:
// True
// SQL方式,連接字符串是server=.;database=db;uid=sa;pwd=sa 2007-1-22 8:21:44

優勢總結

  • 零代碼修改切換資料源(改 config 即可)
  • 新增提供者只需實現抽象類並註冊 config
  • ASP.NET 內建 ProviderBase、ProvidersHelper 簡化樣板代碼
  • 廣泛應用於 Membership、Role、Profile、SessionState 等系統級模組
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved