开发自定义的Provider
asp.net 2.0在很多地方都用到Provider Pattern,比如Personalization、MemberShip等都用到了该模式,其可插拔的特性给开发人员极大的便利,开发人员可以更据自己的需求来开发自己的需要
.Net 2.0中给我们已经定义了一个ProviderBase的抽象类,继承自它我们可以方便的开发自定义的Provider
首先我们写一个抽象类,用来定义好我们需要的抽象方法和接口,为了方便调用,我们为这个类定义了一个静态的构造器,用来实例化该抽象类调用的真正的Provider的实现,并通过Instance()返回其实例化后的对象,我们就可以通过BlogDataProvider.Instance()来调来所用到的实例了
public abstract class BlogDataProvider:ProviderBase
{
private static BlogDataProvider _provider = null;
private static CusProviderCollection<BlogDataProvider> _providers = null;
private static object _lock = new object();
static BlogDataProvider()
{
CreateDefaultCommonProvider();
}
public static BlogDataProvider Instance()
{
return _provider;
}
private static void CreateDefaultCommonProvider()
{
if (_provider ==null)
{
lock (_lock)
{
if (_provider == null)
{
ProvidersConfigSection section = (ProvidersConfigSection)ConfigurationManager.GetSection("system.web/dataService");
//ProviderSettingsCollection Settings = (ProviderSettingsCollection)section["providers"];
_providers = new CusProviderCollection<BlogDataProvider>();
ProvidersHelper.InstantiateProviders(section.Providers, _providers, typeof(BlogDataProvider));
_provider = _providers["SqlBlogDataProvider"];
}
}
}
}
public abstract void AddBlog(DHBlog blog);
public abstract void UpdateBlog(DHBlog blog);
public abstract void DeleteBlog(int id);
}
由于我们用的是ProviderHelper.InstatiateProviders来调用配置文件中定义的类,所以我们还要实现其两个参数定义的类,一个是继承自ConfigurationSection用来读
取配置节点的ProvidersConfigSection
public class ProvidersConfigSection : ConfigurationSection
{
[ConfigurationProperty("providers")]
public ProviderSettingsCollection Providers
{
get
{
return (ProviderSettingsCollection)base["providers"];
}
}
}
还有一个就是实现自ProviderCollection的一个Provider的集合类,因为我们要定义多种不同的Provider所以用一个泛型来实现
public class CusProviderCollection<T>:ProviderCollection
where T:ProviderBase
{
public new T this[string name]
{
get
{
return (T)base[name];
}
}
public override void Add(ProviderBase provider)
{
if (provider == null)
throw new ArgumentNullException("provider");
if (!(provider is T))
throw new ArgumentException
("Invalid provider type", "provider");
base.Add(provider);
}
}
然后是我们要求的类的功能的具体实现
public class SqlBlogDataProvider:BlogDataProvider
{
private string _applicationName;
public string ConnectonString { get; set; }
public override void Initialize(string name, NameValueCollection config)
{
if (config == null)
throw new ArgumentException("config");
if (String.IsNullOrEmpty(name))
name = "SqlBlogDataProvider";
if (string.IsNullOrEmpty(config["description"]))
{
config.Remove("description");
config.Add("description", "SQL Blog provider");
}
base.Initialize(name, config);
_applicationName = config["applicationName"];
if (string.IsNullOrEmpty(_applicationName))
_applicationName = "/";
string strconn = config["connectionStringName"];
if (string.IsNullOrEmpty(strconn))
throw new ProviderException ("Empty or missing connectionStringName");
config.Remove("connectionStringName");
if (ConfigurationManager.ConnectionStrings[strconn] == null)
throw new ProviderException("Missing connection string");
this.ConnectonString = ConfigurationManager.ConnectionStrings[strconn].ConnectionString;
if (String.IsNullOrEmpty(this.ConnectonString))
throw new ProviderException("Empty connection string");
}
public override void AddBlog(DHBlog blog)
{
DataBaseHelper.Insert<DHBlog>(blog);
}
public override void UpdateBlog(DHBlog blog)
{
throw new Exception("The method or operation is not implemented.");
}
public override void DeleteBlog(int id)
{
throw new Exception("The method or operation is not implemented.");
}
}
}
Provider模式是能过配置文件来定义具体要实例化的类的,我们可以在我们的Web.config加入如下代码
<configuration>
<configSections>
<sectionGroup name="system.web">
<section name="dataService"
type="MyDHServer.Compontents.DataProvider.ProvidersConfigSection,MyDHServer.Compontents"
allowDefinition="MachineToApplication"
restartOnExternalChanges="true"/>
</sectionGroup>
</configSections>
</configuration>
.
<system.web>
<dataService>
<providers>
<add name="SqlBlogDataProvider"
type="MyDHServer.DataProvider.SqlDataProvider.SqlBlogDataProvider,MyDHServer.DataProvider"
connectionStringName="MyDHServerConn" />
</providers>
</dataService>
</system.web>