在Cnforum中看見了很多的自定義信息,比如使用什么數據庫,都可以自己定義,那這又是怎么作到的呢,我們就通過CreateUser這個操作來看看怎么獲得系統的配置信息,以及怎么應用它.
首先在注冊用戶頁面的后臺文件(CommunityServerControls\User\CreateUser.cs)中的CreateUser_Click方法有如下語句
CreateUserStatus createUserStatus = Users.Create(user, true);
調用了User對象的Create方法,那我們再來看看Create方法又作了什么呢?
下面是Create方法的完整版
其中的41行使用了CommonDataProvider dp = CommonDataProvider.Instance();
44行是具體的操作User createdUser = dp.CreateUpdateDeleteUser(user, DataProviderAction.Create, out status);
那問題就來了,CommonDataProvider是怎么來的呢,進入CommonDataProvider一看,是一個抽象類,只提供了抽象方法不提供具體實現,而且是用了SingleTon模式來確保只有單一的實例給調用.在CommonDataProvider的構造函數中使用了 CreateDefaultCommonProvider();方法來實例化具體的類
但是這個方法里面只有簡單的3句話
// Get the names of the providers
//
CSConfiguration config = CSConfiguration.GetConfig();
![]()
// Read the configuration specific information
// for this provider
//
Provider sqlForumsProvider = (Provider) config.Providers[CommonDataProviderName];
![]()
// Read the connection string for this provider
//
_defaultInstance = DataProviders.CreateInstance(sqlForumsProvider) as CommonDataProvider;
第一句就是今天的重點了,如何獲得論壇的配置的呢
在CommunityServerComponents\Configuration\Configurations.cs中,GetConfig方法通過讀取磁盤上的communityServer.config文件轉化成XMLDoc,再用此XMLDoc來實例化CSConfiguration對象
具體實例化操作就是一般的讀取XMLNode的過程,就不重復了,但是還有一點需要注意的是,使用了Cache對象封裝了一個CSCache來緩存這些配置信息,這是平時可能會忽略的問題,頻繁的IO操作可是系統性能降低的罪魁禍首哦.
下面就簡單了,CSCConfiguration對象實列化以后就根據配置信息來具體實列化前面的CommonDataProvider,在我系統上是實列化了SQLCommonDataProvider.接下來的就是具體的業務操作了
所以通過這些東西我們可以把自己系統的很多配置包括一些接口實例化的配置都寫在XML的配置文件中,比如具體使用什么數據庫,數據庫的信息等都存在配置信息中,在運行時動態決定生成何種類來進行業務操作,而不用再重新編譯程序
首先在注冊用戶頁面的后臺文件(CommunityServerControls\User\CreateUser.cs)中的CreateUser_Click方法有如下語句
CreateUserStatus createUserStatus = Users.Create(user, true);調用了User對象的Create方法,那我們再來看看Create方法又作了什么呢?
下面是Create方法的完整版
1
public static CreateUserStatus Create(User user, bool sendEmail, bool ignoreDisallowNames) {
2
3
CSEvents.BeforeUser(user, ObjectState.Create);
4![]()
5
CSContext csContext = CSContext.Current;
6
SiteSettings settings = csContext.SiteSettings;
7![]()
8
AccountActivation activation = settings.AccountActivation;
9
CreateUserStatus status;
10
11
string password = user.Password;
12
// 2005-02-26: 新增注冊IP、磁盤限額,格式化昵稱
13
user.Nickname = Globals.HtmlEncode(user.Nickname);
14
User nicknameUser = Users.GetUserByNickname(user.Nickname);
15
if (nicknameUser != null && nicknameUser.UserID > 0)
16
return CreateUserStatus.DuplicateNickname;
17![]()
18
user.Email = Globals.HtmlEncode(user.Email);
19
user.DatabaseQuota = settings.UserDatabaseQuota;
20
user.IPCreated = Globals.IPAddress;
21![]()
22![]()
23
// Lucian: deprecated since it is not handled in CreateUser control
24
// and regEx validation on control's form.
25
// Make sure the username begins with an alpha character
26
//if (!Regex.IsMatch(user.Username, "^[A-Za-z].*"))
27
// return CreateUserStatus.InvalidFirstCharacter;
28![]()
29
// Check if username is disallowed
30
if ((!ignoreDisallowNames) && ( DisallowedNames.NameIsDisallowed(user.Username) == true ))
31
return CreateUserStatus.DisallowedUsername;
32![]()
33
// Strip the domain name from the username, if one is present
34
if( user.Username.IndexOf("\\") > 0 && settings.StripDomainName )
35
user.Username = user.Username.Substring( user.Username.LastIndexOf("\\") + 1 );
36![]()
37
// Set the user's default moderation level
38
user.ModerationLevel = CSContext.Current.SiteSettings.NewUserModerationLevel;
39![]()
40
// Create Instance of the CommonDataProvider
41
CommonDataProvider dp = CommonDataProvider.Instance();
42![]()
43
try {
44
User createdUser = dp.CreateUpdateDeleteUser(user, DataProviderAction.Create, out status);
45
46
47
if(createdUser != null && status == CommunityServer.Components.CreateUserStatus.Created)
48
{
49
csContext.User = createdUser;
50![]()
51
CSConfiguration config = csContext.Config;
52![]()
53
if(settings.EnableDefaultRole && config.DefaultRoles.Length > 0)
54
{
55
foreach(string role in config.DefaultRoles)
56
{
57
CommunityServer.Components.Roles.AddUserToRole(createdUser.Username, role);
58
}
59
}
60![]()
61
// 注冊時默認時區和默認語言
62
createdUser.Profile.Timezone = settings.TimezoneOffset;
63
createdUser.Profile.Language = Globals.Language;
64
createdUser.Profile.Save();
65![]()
66![]()
67
CSEvents.AfterUser(createdUser,ObjectState.Create);
68
}
69![]()
70
71
}
72
catch (CSException e) {
73
return e.CreateUserStatus;
74
}
75![]()
76
// process the emails now
77
//
78
if(sendEmail == true)
79
{
80![]()
81
User currentUser = CSContext.Current.User;
82
if (currentUser.IsForumAdministrator || currentUser.IsBlogAdministrator || currentUser.IsGalleryAdministrator)
83
{
84
activation = AccountActivation.Automatic;
85
}
86
87
// TDD HACK 7/19/2004
88
// we are about to send email to the user notifying them that their account was created, problem is
89
// when we create the user above we can't set the DateCreated property as this is set through the proc
90
// but the email needs to know the DateCreated property. So for now, we'll just set the date to the current
91
// datetime of the server. We don't care about the user local time at this point because the user hasn't
92
// logged in to set their user profile.
93
94
//user.DateCreated = DateTime.Now;
95
//user.LastLogin = DateTime.Now;
96![]()
97
// based on the account type, we send different emails
98
//
99
switch (activation) {
100
case AccountActivation.AdminApproval:
101
Emails.UserAccountPending (user);
102
break;
103
104
case AccountActivation.Email:
105
Emails.UserCreate(user, password);
106
break;
107
108
case AccountActivation.Automatic:
109
Emails.UserCreate(user, password);
110
break;
111
}
112
}
113
114
return CreateUserStatus.Created;
115
}
public static CreateUserStatus Create(User user, bool sendEmail, bool ignoreDisallowNames) {2
3
CSEvents.BeforeUser(user, ObjectState.Create);4

5
CSContext csContext = CSContext.Current;6
SiteSettings settings = csContext.SiteSettings;7

8
AccountActivation activation = settings.AccountActivation;9
CreateUserStatus status;10
11
string password = user.Password;12
// 2005-02-26: 新增注冊IP、磁盤限額,格式化昵稱13
user.Nickname = Globals.HtmlEncode(user.Nickname);14
User nicknameUser = Users.GetUserByNickname(user.Nickname);15
if (nicknameUser != null && nicknameUser.UserID > 0)16
return CreateUserStatus.DuplicateNickname; 17

18
user.Email = Globals.HtmlEncode(user.Email);19
user.DatabaseQuota = settings.UserDatabaseQuota;20
user.IPCreated = Globals.IPAddress;21

22

23
// Lucian: deprecated since it is not handled in CreateUser control24
// and regEx validation on control's form.25
// Make sure the username begins with an alpha character26
//if (!Regex.IsMatch(user.Username, "^[A-Za-z].*"))27
// return CreateUserStatus.InvalidFirstCharacter;28

29
// Check if username is disallowed30
if ((!ignoreDisallowNames) && ( DisallowedNames.NameIsDisallowed(user.Username) == true ))31
return CreateUserStatus.DisallowedUsername;32

33
// Strip the domain name from the username, if one is present34
if( user.Username.IndexOf("\\") > 0 && settings.StripDomainName ) 35
user.Username = user.Username.Substring( user.Username.LastIndexOf("\\") + 1 );36

37
// Set the user's default moderation level38
user.ModerationLevel = CSContext.Current.SiteSettings.NewUserModerationLevel;39

40
// Create Instance of the CommonDataProvider41
CommonDataProvider dp = CommonDataProvider.Instance();42

43
try {44
User createdUser = dp.CreateUpdateDeleteUser(user, DataProviderAction.Create, out status);45
46
47
if(createdUser != null && status == CommunityServer.Components.CreateUserStatus.Created)48
{49
csContext.User = createdUser;50

51
CSConfiguration config = csContext.Config;52

53
if(settings.EnableDefaultRole && config.DefaultRoles.Length > 0)54
{55
foreach(string role in config.DefaultRoles)56
{57
CommunityServer.Components.Roles.AddUserToRole(createdUser.Username, role);58
}59
}60

61
// 注冊時默認時區和默認語言62
createdUser.Profile.Timezone = settings.TimezoneOffset;63
createdUser.Profile.Language = Globals.Language;64
createdUser.Profile.Save();65

66

67
CSEvents.AfterUser(createdUser,ObjectState.Create);68
}69

70
71
}72
catch (CSException e) {73
return e.CreateUserStatus;74
}75

76
// process the emails now77
//78
if(sendEmail == true) 79
{80

81
User currentUser = CSContext.Current.User;82
if (currentUser.IsForumAdministrator || currentUser.IsBlogAdministrator || currentUser.IsGalleryAdministrator) 83
{84
activation = AccountActivation.Automatic;85
}86
87
// TDD HACK 7/19/200488
// we are about to send email to the user notifying them that their account was created, problem is89
// when we create the user above we can't set the DateCreated property as this is set through the proc90
// but the email needs to know the DateCreated property. So for now, we'll just set the date to the current91
// datetime of the server. We don't care about the user local time at this point because the user hasn't92
// logged in to set their user profile.93
94
//user.DateCreated = DateTime.Now;95
//user.LastLogin = DateTime.Now;96

97
// based on the account type, we send different emails98
//99
switch (activation) {100
case AccountActivation.AdminApproval:101
Emails.UserAccountPending (user);102
break;103
104
case AccountActivation.Email:105
Emails.UserCreate(user, password);106
break;107
108
case AccountActivation.Automatic:109
Emails.UserCreate(user, password);110
break;111
}112
}113
114
return CreateUserStatus.Created;115
}其中的41行使用了CommonDataProvider dp = CommonDataProvider.Instance();
44行是具體的操作User createdUser = dp.CreateUpdateDeleteUser(user, DataProviderAction.Create, out status);
那問題就來了,CommonDataProvider是怎么來的呢,進入CommonDataProvider一看,是一個抽象類,只提供了抽象方法不提供具體實現,而且是用了SingleTon模式來確保只有單一的實例給調用.在CommonDataProvider的構造函數中使用了 CreateDefaultCommonProvider();方法來實例化具體的類
但是這個方法里面只有簡單的3句話
// Get the names of the providers
//
CSConfiguration config = CSConfiguration.GetConfig();
// Read the configuration specific information
// for this provider
//
Provider sqlForumsProvider = (Provider) config.Providers[CommonDataProviderName];
// Read the connection string for this provider
//
_defaultInstance = DataProviders.CreateInstance(sqlForumsProvider) as CommonDataProvider;第一句就是今天的重點了,如何獲得論壇的配置的呢
在CommunityServerComponents\Configuration\Configurations.cs中,GetConfig方法通過讀取磁盤上的communityServer.config文件轉化成XMLDoc,再用此XMLDoc來實例化CSConfiguration對象
具體實例化操作就是一般的讀取XMLNode的過程,就不重復了,但是還有一點需要注意的是,使用了Cache對象封裝了一個CSCache來緩存這些配置信息,這是平時可能會忽略的問題,頻繁的IO操作可是系統性能降低的罪魁禍首哦.
下面就簡單了,CSCConfiguration對象實列化以后就根據配置信息來具體實列化前面的CommonDataProvider,在我系統上是實列化了SQLCommonDataProvider.接下來的就是具體的業務操作了
所以通過這些東西我們可以把自己系統的很多配置包括一些接口實例化的配置都寫在XML的配置文件中,比如具體使用什么數據庫,數據庫的信息等都存在配置信息中,在運行時動態決定生成何種類來進行業務操作,而不用再重新編譯程序


浙公網安備 33010602011771號