实现分布式的Membership和上下文传递剖析Word格式文档下载.docx
《实现分布式的Membership和上下文传递剖析Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《实现分布式的Membership和上下文传递剖析Word格式文档下载.docx(18页珍藏版)》请在冰豆网上搜索。
我们将该自定义MembershipProvider称为RemoteMembershipProvider。
图2揭示了RemoteMembershipProvider实现的原理:
RemoteMembershipProvider通过调用WCF服务MembershipService提供对成员资格所有功能的实现;
MembershipService则通过调用Membership实现服务;
最终的实现还是落在了SqlMembershipProvider这个原生的MembershipProvider上。
clip_image004
图2RemoteMembershipProvider实现原理
1、服务契约和服务实现
首先来看看MembershipService实现的服务契约的定义。
由于MembershipService最终是为RemoteMembershipProvider这个自定义MembershipProvider服务的,所以服务操作的定义是基于MembershipProvider的API定义。
MembershipProvider包含两种类型的成员:
属性和方法,简单起见,我们可以为MembershipProvider每一个抽象方法定义一个匹配的服务操作;
而对于所有属性,完全采用服务端(应用服务器)的MembershipProvider相关属性。
在RemoteMembershipProvider初始化的时候通过调用MembershipService获取所有服务端MembershipProvider的配置信息。
为此,我们为MembershipProvider的所有属性定义了一个数据契约:
MembershipConfigData。
在PetShop中,MembershipConfigData和服务契约一起定义在Infrastructures.Service.Interface项目中。
1:
usingSystem.Runtime.Serialization;
2:
usingSystem.Web.Security;
3:
namespaceArtech.PetShop.Infrastructures.Service.Interface
4:
{
5:
[DataContract(Namespace="
6:
publicclassMembershipConfigData
7:
8:
[DataMember]
9:
publicstringApplicationName
10:
{get;
set;
}
11:
12:
13:
publicboolEnablePasswordReset
14:
15:
16:
17:
publicboolEnablePasswordRetrieval
18:
19:
20:
21:
publicintMaxInvalidPasswordAttempts
22:
23:
24:
25:
publicintMinRequiredNonAlphanumericCharacters
26:
27:
28:
29:
publicintMinRequiredPasswordLength
30:
31:
32:
33:
publicintPasswordAttemptWindow
34:
35:
36:
37:
publicMembershipPasswordFormatPasswordFormat
38:
39:
40:
41:
publicstringPasswordStrengthRegularExpression
42:
43:
44:
45:
publicboolRequiresQuestionAndAnswer
46:
47:
48:
49:
publicboolRequiresUniqueEmail
50:
51:
52:
在服务契约中,定义了一个额外的方法GetMembershipConfigData获取服务端MembershipProvider的所有配置信息,而对于服务操作的定义,则与MembershipProvider同名抽象方法相对应。
usingSystem.ServiceModel;
[ServiceContract(Namespace="
publicinterfaceIMembershipService
[OperationContract]
boolChangePassword(stringusername,stringoldPassword,stringnewPassword);
boolChangePasswordQuestionAndAnswer(stringusername,stringpassword,stringnewPasswordQuestion,stringnewPasswordAnswer);
MembershipUserCreateUser(stringusername,stringpassword,stringemail,stringpasswordQuestion,stringpasswordAnswer,boolisApproved,objectproviderUserKey,outMembershipCreateStatusstatus);
boolDeleteUser(stringusername,booldeleteAllRelatedData);
MembershipUserCollectionFindUsersByEmail(stringemailToMatch,intpageIndex,intpageSize,outinttotalRecords);
MembershipUserCollectionFindUsersByName(stringusernameToMatch,intpageIndex,intpageSize,outinttotalRecords);
MembershipUserCollectionGetAllUsers(intpageIndex,intpageSize,outinttotalRecords);
intGetNumberOfUsersOnline();
stringGetPassword(stringusername,stringanswer);
[OperationContract(Name="
GetUserByName"
)]
MembershipUserGetUser(stringusername,booluserIsOnline);
GetUserByID"
MembershipUserGetUser(objectproviderUserKey,booluserIsOnline);
stringGetUserNameByEmail(stringemail);
stringResetPassword(stringusername,stringanswer);
boolUnlockUser(stringuserName);
voidUpdateUser(MembershipUseruser);
boolValidateUser(stringusername,stringpassword);
MembershipConfigDataGetMembershipConfigData();
服务的实现,则异常简单,我们须要做的仅仅是通过Membership.Provider获得当前的MembershipProvider,调用同名的属性或方法即可。
MembershipService定义在Infrastructures.Service中,定义如下:
usingArtech.PetShop.Infrastructures.Service.Interface;
namespaceArtech.PetShop.Infrastructures.Service
publicclassMembershipService:
IMembershipService
#regionIMembershipServiceMembers
publicboolChangePassword(stringusername,stringoldPassword,stringnewPassword)
returnMembership.Provider.ChangePassword(username,oldPassword,newPassword);
publicboolChangePasswordQuestionAndAnswer(stringusername,stringpassword,stringnewPasswordQuestion,stringnewPasswordAnswer)
returnMembership.Provider.ChangePasswordQuestionAndAnswer(username,password,newPasswordQuestion,newPasswordAnswer);
//其他成员
publicMembershipConfigDataGetMembershipConfigData()
returnnewMembershipConfigData
ApplicationName=Membership.Provider.ApplicationName,
EnablePasswordReset=Membership.Provider.EnablePasswordReset,
EnablePasswordRetrieval=Membership.Provider.EnablePasswordRetrieval,
MaxInvalidPasswordAttempts=Membership.Provider.MaxInvalidPasswordAttempts,
MinRequiredNonAlphanumericCharacters=Membership.Provider.MinRequiredNonAlphanumericCharacters,
MinRequiredPasswordLength=Membership.Provider.MinRequiredPasswordLength,
PasswordAttemptWindow=Membership.Provider.PasswordAttemptWindow,
PasswordFormat=Membership.Provider.PasswordFormat,
PasswordStrengthRegularExpression=Membership.Provider.PasswordStrengthRegularExpression,
RequiresQuestionAndAnswer=Membership.Provider.RequiresQuestionAndAnswer,
RequiresUniqueEmail=Membership.Provider.RequiresUniqueEmail
};
#endregion
2、RemoteMembershipProvider的实现
由于RemoteMembershipProvider完全通过调用WCF服务的方式提供对所有成员资格功能的实现,所以进行RemoteMembershipProvider配置时,配置相应的终结点就可以了。
<
?
xmlversion="
1.0"
>
configuration>
system.web>
membershipdefaultProvider="
RemoteProvider"
providers>
addname="
type="
Artech.PetShop.Infrastructures.RemoteMembershipProvider,Artech.PetShop.Infrastructures,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"
endpoint="
membershipservice"
/>
/providers>
/membership>
/system.web>
system.serviceModel>
client>
endpointaddress="
http:
//localhost/PetShop/Infrastructures/MembershipService.svc"
behaviorConfiguration="
petShopBehavior"
binding="
ws2007HttpBinding"
contract="
Artech.PetShop.Infrastructures.Service.Interface.IMembershipService"
name="
/client>
/system.serviceModel>
/configuration>
在RemoteMembershipProvider中,通过Initialize方法获取配置的终结点名称并创建服务代理。
通过该代理调用GetMembershipConfigData操作获取服务端MembershipProvider的配置信息,并对RemoteMembershipProvider进行初始化,RemoteMembershipProvider定义如下:
usingSystem.Collections.Specialized;
usingSystem.Configuration;
usingSystem.Linq;
usingArtech.PetShop.Common;
namespaceArtech.PetShop.Infrastructures
publicclassRemoteMembershipProvider:
MembershipProvider
privatebool_enablePasswordReset;
privatebool_enablePasswordRetrieval;
//其他字段成员
publicIMembershipServiceMembershipProxy
privateset;
}
publicoverrideintMaxInvalidPasswordAttempts
get{returnthis._maxInvalidPasswordAttempts;
//其他属性成员
publicoverridevoidInitialize(stringname,NameValueCollectionconfig)
if(!
config.AllKeys.Contains<
string>
("
endpoint"
))
thrownewConfigurationErrorsException("
Missingthemandatory\"
endpoint\"
configuraitonproperty."
);
this.MembershipProxy=ServiceProxyFactory.Create<
IMembershipService>
(config["
]);
base.Initialize(name,config);
MembershipConfigDataconfigData=this.MembershipProxy.GetMembershipConfigData();
this.ApplicationName=configData.ApplicationName;
this._enablePasswordReset=configData.EnablePasswordReset;
this._enablePasswordRetrieval=configData.EnablePasswordRetrieval;
//......
对于其他抽象方法的实现,仅仅须要通过上面创建的服务代理,调用相应的服务操作即可。
注:
为了避免在服务操作调用后频繁地进行服务代理的关闭(Close)和终止(Abort)操作,我们采用基于AOP的方式实现服务的调用,将这些操作封装到一个自定义的RealProxy中,并通过ServiceProxyFactory<
T>
创建该