將抽象契約與具體實現分離,通過配置文件動態載入提供者,實現儲存介質(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();
}
<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
ProviderBase、ProvidersHelper 簡化樣板代碼