ASP.net 2.0 的 Provider 模型为开发者提供了将他们自己的实现作为一种特性加入到运行时的可扩展方法。Membership Provider 与 Role Provider 在 ASP.net 2.0 中都通过细化一个接口或者协议来遵循 Provider 的模型。如果你创建你的组件来实现 Provider 模型定义的协议,你可以插入你的代码到 ASP.net 运行时并且替换或者扩展已经存在的 Provider。在 ASP.net 2.0 的 Provider 模型包括一个 Provider 配置与初始化的基础结构。
Provider 模型从抽象类 ProviderBase 开始。ProviderBase 强迫协议为所有的 Provider 需要公共名称与描述属性,就像一个公共初始化方法一样。MembershipProvider 与 RoleProvider 是继承自 ProviderBase 的抽象类。这些类添加额外的属性与方法来定义它们特殊功能的接口。
举例来说,MembershipProvider 需要一个 membership 类来实现一个 ValidateUser 方法。2.0中默认的 Membership Provider ,SqlMembershipProvider,通过在一个 SQL Server 数据库中执行一个存储过程实现了这个方法。如果你想自己写 Provider 是来使用 XML 文件存储成员资格信息,你将不得不自己写 ValidateUser 的代码来通过存储在 XML 文件中的信息来验证用户的密码。
Provider 模型的美妙之处在于:高层的应用程序服务可以在 Provider 上建立并且不需要知道接口之后的细节。一个很好的例子是 ASP.net 2.0 的 Membership Provider 控件,包括 Login 控件,CreateUser 控件,LoginStatus 控件等等。所有这些控件遵循 MembershipProvider 协议。在某些时候,Login 控件需要在配置好的 Provider 中调用 ValidateUser 方法。Login 控件不关心是否有对 SQL Server 数据库或者 XML 文件的访问。所有的 Login 控件关心的是通过用户名与密码在返回值中得到的是真还是假。
提供程序模型最重要的方面是:实现(例如,将数据保留成文本文件还是保留在数据库中)是从应用程序代码中抽象出来的。在配置文件中会指定针对给定功能的提供程序的类型,该提供程序是实现特定的。接着,功能级别的提供程序会读取来自配置文件的类型,并充当功能代码工厂。然后,应用程序开发人员就可以在应用程序代码中使用这些功能类。在配置文件中,可以换出实现类型,从而不再需要为适应不同的实现方法而重写代码。
ASP.NET 中包含的提供程序大部分都是数据持久性实现的抽象,这些数据持久性实现是针对诸如配置文件或成员资格这类功能的。但是,此模型还可应用于任何其他类型的功能,这些功能可以使用多种方式进行抽象和实现。
<membership defaultProvider="PTMembershipProvider">
<providers>
<add name="PTMembershipProvider" type="PTMembershipProvider" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" applicationName="/" requiresUniqueEmail="false" passwordFormat="Clear" description="Stores and retrieves membership 
 data using CSLA .NET business objects."/>
</providers>
</membership>
public class PTMembershipProvider : MembershipProvider
...{
public override bool ValidateUser(
string username, string password)
...{
bool result = PTPrincipal.Login(username, password);
HttpContext.Current.Session["CslaPrincipal"] =
Csla.ApplicationContext.User;
return result;
}
Non-Implemented Members#region Non-Implemented Members
// the following members must be implemented due to the abstract class MembershipProvider,
// but not required to be functional for using the Login control.
public override bool ChangePassword(string username, string oldPassword, string newPassword)
...{
throw new NotSupportedException("The method or operation is not implemented.");
}
public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
...{
throw new NotSupportedException("The method or operation is not implemented.");
}
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
...{
throw new NotSupportedException("The method or operation is not implemented.");
}
public override bool DeleteUser(string username, bool deleteAllRelatedData)
...{
throw new NotSupportedException("The method or operation is not implemented.");
}
public override bool EnablePasswordReset
...{
get ...{ throw new NotSupportedException("The method or operation is not implemented."); }
}
public override bool EnablePasswordRetrieval
...{
get ...{ throw new NotSupportedException("The method or operation is not implemented."); }
}
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
...{
throw new NotSupportedException("The method or operation is not implemented.");
}
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
...{
throw new NotSupportedException("The method or operation is not implemented.");
}
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
...{
throw new NotSupportedException("The method or operation is not implemented.");
}
public override int GetNumberOfUsersOnline()
...{
throw new NotSupportedException("The method or operation is not implemented.");
}
public override string GetPassword(string username, string answer)
...{
throw new NotSupportedException("The method or operation is not implemented.");
}
public override MembershipUser GetUser(string username, bool userIsOnline)
...{
throw new NotSupportedException("The method or operation is not implemented.");
}
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
...{
throw new NotSupportedException("The method or operation is not implemented.");
}
public override string GetUserNameByEmail(string email)
...{
throw new NotSupportedException("The method or operation is not implemented.");
}
public override int MaxInvalidPasswordAttempts
...{
get ...{ throw new NotSupportedException("The method or operation is not implemented."); }
}
public override int MinRequiredNonAlphanumericCharacters
...{
get ...{ throw new NotSupportedException("The method or operation is not implemented."); }
}
public override int MinRequiredPasswordLength
...{
get ...{ throw new NotSupportedException("The method or operation is not implemented."); }
}
public override int PasswordAttemptWindow
...{
get ...{ throw new NotSupportedException("The method or operation is not implemented."); }
}
public override MembershipPasswordFormat PasswordFormat
...