自.net 2.0出世时,Provider模式就随处可见了,如:MembershipProvider、SiteMapProvider等,
它的出现使我们的应用程序有了更大的扩展性,可以是一个数据工厂的提供者,也可以是一个逻辑处理的提供者。
而实现这种模式却是相当的简单,只需实现以下四步即可:
1、定义一个类,抽象出我们所需要的操作,基类为ProviderBase
如:
Code
public abstract class RssProvider : ProviderBase
{
public abstract void LoadRss();
public abstract void AddRss();
}
public abstract class RssProvider : ProviderBase
{
public abstract void LoadRss();
public abstract void AddRss();
}
2、实现一个Section,用来从配置文件中读取Provider的相关配置,该类继承于ConfigurationSection
Code
public class RssProviderSection : ConfigurationSection
{
[ConfigurationProperty("providers")]
public ProviderSettingsCollection Providers
{
get { return (ProviderSettingsCollection)base["providers"]; }
set { base["providers"] = value; }
}
[StringValidator(MinLength=1)]
[ConfigurationProperty("defaultProvider", DefaultValue = "XmlProvider")]
public string DefaultProvider
{
get { return (string)base["defaultProvider"]; }
set { base["defaultProvider"] = value; }
}
}
public class RssProviderCollection : ProviderCollection
{
//从索引器中获取指定名称的Provider
public new RssProvider this[string name]
{
get
{
return (RssProvider)base[name];
}
}
public override void Add(ProviderBase provider)
{
if (provider == null)
{
throw new ArgumentNullException("provider");
}
if (provider is RssProvider)
{
base.Add(provider);
}
}
}
public class RssProviderSection : ConfigurationSection
{
[ConfigurationProperty("providers")]
public ProviderSettingsCollection Providers
{
get { return (ProviderSettingsCollection)base["providers"]; }
set { base["providers"] = value; }
}
[StringValidator(MinLength=1)]
[ConfigurationProperty("defaultProvider", DefaultValue = "XmlProvider")]
public string DefaultProvider
{
get { return (string)base["defaultProvider"]; }
set { base["defaultProvider"] = value; }
}
}
public class RssProviderCollection : ProviderCollection
{
//从索引器中获取指定名称的Provider
public new RssProvider this[string name]
{
get
{
return (RssProvider)base[name];
}
}
public override void Add(ProviderBase provider)
{
if (provider == null)
{
throw new ArgumentNullException("provider");
}
if (provider is RssProvider)
{
base.Add(provider);
}
}
}
3、在调用时用RssProviderSection去读取配置文件,并加载指定的Provider
Code
public class RssService
{
private static RssProvider _provider;
private static RssProviderCollection _providers;
private static readonly object obj = new object();
public static RssProvider Provider
{
get
{
LoadProvider();
return _provider;
}
}
public static RssProviderCollection Providers
{
get {
LoadProvider();
return _providers; }
}
public static void LoadProvider()
{
if (_provider == null)
{
lock (obj)
{
if (_provider == null)
{
RssProviderSection section = (BlogProviderSection)System.Configuration.ConfigurationManager.GetSection("Blog/RssService");
_providers = new RssProviderCollection();
ProvidersHelper.InstantiateProviders(section.Providers, _providers, typeof(BlogProvider));
_provider = _providers[section.DefaultProvider];
if (_provider == null)
throw new ProviderException("null");
}
}
}
}
}
public class RssService
{
private static RssProvider _provider;
private static RssProviderCollection _providers;
private static readonly object obj = new object();
public static RssProvider Provider
{
get
{
LoadProvider();
return _provider;
}
}
public static RssProviderCollection Providers
{
get {
LoadProvider();
return _providers; }
}
public static void LoadProvider()
{
if (_provider == null)
{
lock (obj)
{
if (_provider == null)
{
RssProviderSection section = (BlogProviderSection)System.Configuration.ConfigurationManager.GetSection("Blog/RssService");
_providers = new RssProviderCollection();
ProvidersHelper.InstantiateProviders(section.Providers, _providers, typeof(BlogProvider));
_provider = _providers[section.DefaultProvider];
if (_provider == null)
throw new ProviderException("null");
}
}
}
}
}
4、配置文件
Code
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="Blog">
<section name="RssService" type="ClassLib.BlogProviderSection,ClassLib"/>
</sectionGroup>
</configSections>
<Blog>
<RssService defaultProvider="XmlProvider">
<providers>
<add name="XmlProvider" type="ClassLib.XmlProvider,ClassLib"></add>
<add name="SqlProvider" type="ClassLib.SqlProvider,ClassLib"></add>
</providers>
</RssService>
</Blog>
</configuration>
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="Blog">
<section name="RssService" type="ClassLib.BlogProviderSection,ClassLib"/>
</sectionGroup>
</configSections>
<Blog>
<RssService defaultProvider="XmlProvider">
<providers>
<add name="XmlProvider" type="ClassLib.XmlProvider,ClassLib"></add>
<add name="SqlProvider" type="ClassLib.SqlProvider,ClassLib"></add>
</providers>
</RssService>
</Blog>
</configuration>
更多内容可以去MSDN查阅ProviderBase基类
如果山不向我走来,我就向山走去!