mojoportal学习笔记之How to Write a Provider Model
在学习 mojoportal时,看到mojoportal调用editor使用了provider,顺便温习一下provider模式。
How to Write a Provider Model
原文地址: http://dotnetslackers.com/articles/designpatterns/HowToWriteAProviderModel.aspx)
这里只是简要的学习一下,做个笔记
自定义建立provider ,分四步
第一步: Main Data Provider Class
Main Data Provider Class 也是一个抽象类,定义了所有相关的数据操作方法。
这个抽象的数据操作方法类必须继承自System.Configuration.Provider.ProviderBase 基类
举例:
using System; 2
using System.Collections.Generic; 3
using System.Linq; 4
using System.Text; 5
using System.Configuration.Provider; 6
7
namespace SampleProvider 8
{ 9
public abstract class DataProvider : ProviderBase 10
{ 11
// Adds a text value for a specified ID to the storage 12
public abstract void AddText(int id, string text); 13
14
// Gets the text associated to a specified ID 15
public abstract string GetText(int id); 16
} 17
} 正如你看到的,这个main provider class 继承自
ProviderBase抽象类,定义了两个抽象方法,这两个方法需要被不同的provider 实现你应该明白,这个main provider class 是你的provider 中抽象的方法定义的地方。
第二步:Data Provider Collection
provider 集合类,继承自
System.Configuration.ProviderCollection基类ProviderCollection 类暴露了几个方法处理配置文件中定义的provider类关键的一点是,providerCollection类返回main provider class 一个实例
代码如下:
Listing 2: Data provider collection class 2
using System; 3
using System.Collections.Generic; 4
using System.Linq; 5
using System.Text; 6
using System.Configuration.Provider; 7
8
namespace SampleProvider 9
{ 10
public class DataProviderCollection : ProviderCollection 11
{ 12
// Return an instance of DataProvider 13
// for a specified provider name 14
new public DataProvider this[string name] 15
{ 16
get { return (DataProvider)base[name]; } 17
} 18
} 19
} 第三步:Data Provider Configuration
下一步工作是写一个 data provider configuration 类,用来读取配置文件
这个类需要引用
System.Configuration.ConfigSection命名空间.
在你的配置类中,你需要定义一个类型为System.Configuraiton.ProviderSettingsCollection的属性。
这个属性会从基类中返回一个实例。
这个类中,所有属性必须装饰 ConfigurationProperty 标签
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
using System.Configuration;
6
7
namespace SampleProvider
8
{
9
public class DataProviderConfiguration : ConfigurationSection
10
{
11
[ConfigurationProperty("providers")]
12
public ProviderSettingsCollection Providers
13
{
14
get
15
{
16
return (ProviderSettingsCollection)base["providers"];
17
}
18
}
19
20
[ConfigurationProperty("default", DefaultValue = "SqlProvider")]
21
public string Default
22
{
23
get
24
{
25
return (string)base["default"];
26
}
27
set
28
{
29
base["default"] = value;
30
}
31
}
32
}
33
}
上面的代码中,定义了2个属性,第一个属性类型是ProviderSettingsCollection,名称是Providers
它映射到配置文件的<providers /> 元素
第二个方法设置了默认provider的名称,默认使用sqlProvider.
第四步:Data Provider Manager
这一步中你不需要继承接口或基类,只要根据你的需求来写。
data provider Manager的主要目的是初始化一个具体的 provider类,并在内存中加载配置信息。
初始化时,你需要为你的data provider获取配置信息,并在内存中建立一个具体的实例。
为了使代码工作,你的Data Provider Manager类中必须包含一个静态的public Initialize方法
代码如下:
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
using System.Configuration;
6
using System.Web.Configuration;
7
8
namespace SampleProvider
9
{
10
public class DataProviderManager
11
{
12
private static DataProvider defaultProvider;
13
private static DataProviderCollection providers;
14
15
static DataProviderManager()
16
{
17
Initialize();
18
}
19
20
private static void Initialize()
21
{
22
DataProviderConfiguration configuration =
23
(DataProviderConfiguration)
24
ConfigurationManager.GetSection("SampleProvider");
25
26
if (configuration == null)
27
throw new ConfigurationErrorsException
28
("SampleProvider configuration section is not set correctly.");
29
30
providers = new DataProviderCollection();
31
32
ProvidersHelper.InstantiateProviders(configuration.Providers
33
, providers, typeof(DataProvider));
34
35
providers.SetReadOnly();
36
37
defaultProvider = providers[configuration.Default];
38
39
if (defaultProvider == null)
40
throw new Exception("defaultProvider");
41
}
42
43
public static DataProvider Provider
44
{
45
get
46
{
47
return defaultProvider;
48
}
49
}
50
51
public static DataProviderCollection Providers
52
{
53
get
54
{
55
return providers;
56
}
57
}
58
}
59
}
Default Sql Data Provider
using System; 2
using System.Collections.Generic; 3
using System.Linq; 4
using System.Text; 5
using System.Data.SqlClient; 6
using System.Configuration; 7
using System.Collections.Specialized; 8
9
namespace SampleProvider 10
{ 11
public class SqlDataProvider : DataProvider 12
{ 13
private string _connectionString = string.Empty; 14
15
public override void Initialize(string name, NameValueCollection config) 16
{ 17
base.Initialize(name, config); 18
19
this._connectionString = config["connectionString"]; 20
21
if (string.IsNullOrEmpty(this._connectionString)) 22
throw new ConfigurationErrorsException 23
("connectionString must be set to the appropriate value"); 24
} 25
26
public override void AddText(int id, string text) 27
{ 28
using (SqlConnection connection = new SqlConnection(this._connectionString)) 29
{ 30
// For real world scnearios use parameterized SQL to avoid SQL injections! 31
string commandText = string.Format 32
("INSERT INTO SampleTable (Id, Value) VALUES ({0}, '{1}')", id, text); 33
SqlCommand command = new SqlCommand(commandText, connection); 34
command.CommandType = System.Data.CommandType.Text; 35
36
connection.Open(); 37
command.ExecuteNonQuery(); 38
connection.Close(); 39
command.Dispose(); 40
} 41
} 42
43
public override string GetText(int id) 44
{ 45
string result = string.Empty; 46
47
using (SqlConnection connection = new SqlConnection(this._connectionString)) 48
{ 49
string commandText = string.Format("SELECT Value FROM SampleTable WHERE Id = {0}", id); 50
SqlCommand command = new SqlCommand(commandText, connection); 51
command.CommandType = System.Data.CommandType.Text; 52
53
connection.Open(); 54
55
result = command.ExecuteScalar() as string; 56
57
connection.Close(); 58
command.Dispose(); 59
} 60
61
return result; 62
} 63
} 64

添加配置文件
1:在<configSections> </configSections>中添加代码如下
<configSections>
<section name="SampleProvider"
type="SampleProvider.DataProviderConfiguration, SampleProvider" />
</configSections>
2<configuration > </configuration>中添加代码如下
<SampleProvider default="SqlProvider">
<providers>
<add name="SqlProvider"
type="SampleProvider.SqlDataProvider, SampleProvider"
connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\DB.mdf;Integrated
curity=True;User Instance=True" />
</providers>
</SampleProvider>
测试代码如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="SampleSite._Default" %> 2
3
<%@ Import Namespace="SampleProvider" %> 4
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 5
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 6
<html xmlns="http://www.w3.org/1999/xhtml"> 7
8
<script runat="server" language="c#"> 9
protected void btnAdd_Click(object sender, EventArgs e) 10
{ 11
try 12
{ 13
DataProviderManager.Provider.AddText 14
(Convert.ToInt32(txtId.Text), txtValue.Text); 15
lblResult.Text = "Data added successfully!"; 16
} 17
catch (Exception ex) 18
{ 19
lblResult.Text = ex.Message + "<br /> " + ex.StackTrace; 20
} 21
} 22
23
protected void btnSelect_Click(object sender, EventArgs e) 24
{ 25
try 26
{ 27
lblData.Text = DataProviderManager.Provider.GetText 28
(Convert.ToInt32(txtIdToSelect.Text)); 29
} 30
catch (Exception ex) 31
{ 32
lblData.Text = ex.Message + "<br /> " + ex.StackTrace; 33
} 34
} 35
</script> 36
37
<head runat="server"> 38
<title>Untitled Page</title> 39
</head> 40
<body> 41
<form id="form1" runat="server"> 42
<div> 43
<h1> 44
Add Data</h1> 45
Enter ID: <asp:TextBox ID="txtId" runat="server"></asp:TextBox><br /> 46
Enter Value: <asp:TextBox ID="txtValue" runat="server"></asp:TextBox><br /> 47
<asp:Button ID="btnAdd" runat="server" Text="Add" OnClick="btnAdd_Click" /><br /> 48
<asp:Label ID="lblResult" runat="server" Text=""></asp:Label> 49
</div> 50
<div> 51
<h1> 52
Select Data</h1> 53
Enter ID: <asp:TextBox ID="txtIdToSelect" runat="server"></asp:TextBox><br /> 54
<asp:Button ID="btnSelect" runat="server" Text="Select" OnClick="btnSelect_Click" /><br /> 55
<asp:Label ID="lblData" runat="server" Text=""></asp:Label> 56
</div> 57
</form> 58
</body> 59
</html>


浙公网安备 33010602011771号