65.9K
CodeProject 正在变化。 阅读更多。
Home

初学者的 Provider 模式

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.75/5 (26投票s)

2013年2月21日

CPOL

2分钟阅读

viewsIcon

172048

downloadIcon

1454

本文介绍了 Provider 模式的基本概念。


下载 ProviderPattern.zip

引言

Provider 模式允许开发人员创建可插拔的组件。 它最初在 Framework 2.0 中引入,并且具有许多功能,例如“Membership Provider”,“Roles Provider”等,并使用配置文件进行实例化。

本文提供了使用 Provider 模式创建日志记录组件的指南。 示例项目包含两个 Provider “TextLogProvider”和“XmlLogProvider”。您可以在配置文件中将其中一个设置为默认值。

基础数据 Provider 类

首先,您需要定义所有方法的抽象表示。 创建您的数据 Provider 基类,并且您的类必须继承自 System.Configuration.Provider.ProviderBase 基类。

    
 public abstract class LogProviderBase : ProviderBase
 {  
    .    
    public abstract void WriteLog(LogType logType, string message);
    .        
 }

正如您所见,LogProviderBase 是一个抽象类,它具有抽象方法 WriteLog(..)。 在此示例中,我们只有一个抽象方法。 但是,我们可以根据需要拥有多个。

数据 Provider 类

创建基础 Provider 类后,现在可以创建具体的 Provider 类。 在此示例中,我将创建两个 Provider 用于日志记录,一个用于文本,第二个用于 XML。 从 LogProviderBase 类派生具体 Provider 类,并实现抽象方法。

 public class TextLogProvider : LogProviderBase
 {
 
    #region Data Members
 
    private string _filePath = "";
 
    #endregion
 
    #region Overrided Methods
 
    public override void SetParameters(System.Collections.Specialized.NameValueCollection config)
    {
        _filePath = config["fileLocation"];
    }
 
    public override void WriteLog(LogType logType, string message)
    {
        var dir = Path.GetDirectoryName(_filePath);
        if (!Directory.Exists(dir))
            Directory.CreateDirectory(dir);
 
        using (var sw = new StreamWriter(_filePath, true))
        {
            string s = string.Format("{0}, {1}, {2}", DateTime.Now, logType.ToString(), message);
            sw.WriteLine(s);
        }
    }
 
    #endregion
 
 }    
    

通过实现 WriteLog(…),根据您的 Provider 类型编写日志记录逻辑。 在 TextLogProvider 类中,我将 CVS 行保存在文本文件中。

Provider 集合 & 配置节

为了处理 Provider 配置,您必须编写自己的 Provider 集合类,该类派生自 System.Configuration.ProviderCollection 类。 ProviderCollection 类公开属性和方法,以使用在配置文件中声明的各种数据 Provider 的列表。

 public class LogProviderCollection : ProviderCollection
 {
    new public LogProviderBase this[string name]
    {
        get { return (LogProviderBase)base[name]; }
    }
 }
    

Provider 模式从配置文件中读取具体 Provider,为此,您需要另一个类,该类将从配置文件中读取所有 Provider 集合。 创建从 System.Configuration.ConfigurationSection 文件派生的 ProviderConfiguration 类。

 public class LogProviderConfiguration : ConfigurationSection
 {
 
    [ConfigurationProperty("providers")]
    public ProviderSettingsCollection Providers
    {
        get
        {
            return (ProviderSettingsCollection)base["providers"];
        }
    }
 
    [ConfigurationProperty("default", DefaultValue = "XmlProvider")]
    public string DefaultProviderName
    {
        get
        {
            return base["default"] as string;
        }
    }
 
 }
    

在此类中,您可以根据需要从配置节中提取的不同参数添加任意数量的属性。 所有属性必须使用 ConfigurationProperty 属性进行修饰。

配置

为了配置 Provider 模型,我们需要在 <configsections> 中定义我们的 Provider 配置节。 在这里,我们可以添加一个 <section> 元素,其中包含 Provider 模型配置节元素的名称和我们的数据 Provider 配置类的类型。

配置节之后(我们将 LogProviders 配置为节名称)。 现在,我们需要将所有可用的 Provider 添加到其中,并从中设置一个默认 Provider。

    
  <configSections>
    <section name="LogProviders"
      type="ProviderPatternLogTest.LogProvider.LogProviderConfiguration, ProviderPatternLogTest"/>
  </configSections>
 

  <LogProviders default="XmlProvider">
    <providers>
 
      <add name="XmlProvider"
        type="ProviderPatternLogTest.LogProvider.Providers.XmlLogProvider, ProviderPatternLogTest"
        fileLocation="c:\temp\log.xml"/>
 
      <add name="TextProvider"
        type="ProviderPatternLogTest.LogProvider.Providers.TextLogProvider, ProviderPatternLogTest"
        fileLocation="c:\temp\log.txt"/>
 
    </providers>
  </LogProviders>
    

在代码中使用 Provider 模型

在您的代码中使用 Provider 模型非常容易,只需获取 Provider Manager 类的默认属性,然后调用您的具体方法即可

    
 LogProviderManager.Default.WriteLog(logType, txtMessage.Text);
    
    

获取其他信息

您还可以轻松获取有关具体 Provider 的其他有用信息。 只需使用 LogProviderManager 获取 ProviderSetting。

 var setting = LogProviderManager.ProviderSettings[defaultName];
    
 var setStr = GetSetting(setting);
 
 MessageBox.Show(setStr);
    

GetSetting(...) 方法仅解析所有参数并返回连接的字符串消息。

 private string GetSetting(ProviderSettings setting)
 {
    StringBuilder str = new StringBuilder();
    str.AppendLine(string.Format("Default Provider name: {0}", setting.Name));
    str.AppendLine(string.Format("Default Provider type: {0}", setting.Type));
    str.AppendLine("------------------Parameters--------------------");
    foreach (String s in setting.Parameters)
    {
 
        str.AppendLine(string.Format("Parameter: {0} -> {1}", s, setting.Parameters.Get(s)));
    }
    str.AppendLine("---------------------------------------");
    str.AppendLine("");
 
    return str.ToString();
 }
    
© . All rights reserved.