我们在 Azure SQL 数据库上有一个基于 ASP.net sqlMembershipProvider 的用户数据库。很明显,开箱即用的 sqlMembershipProvider 4.0 没有 Azure SQL 连接所需的重试逻辑,这些逻辑可能会因节流而丢失或可能过期。
可以实现我们自己的具有此功能的成员资格提供程序,但它必须与标准 sqlMembershipProvider 4.0 完全相同的数据库交互才能与我们数据库中的现有用户一起工作。但是,为此需要查看原始 sqlMembershipProvider 4.0 的源代码,此代码自 2.0 版以来尚未公开发布,因此我的问题是:
将重试逻辑放入 sqlMembershipProvider 的最省力的方法是什么?或者这会反射(reflect) System.web.security.sqlMembershipProvider 中 sqlMembershipProvider 4.0 的代码,并创建一个与 sqlMembershipProvider 具有相同功能但使用重试逻辑(例如 Microsoft TransientFaultHandling ReliableSqlConnection 的重试逻辑)的自定义成员资格提供者?考虑到 Microsoft 对 asp.net 库的许可,这样做是否合法(反射(reflect)和创建类似的代码但具有附加功能),例如。系统.Web?
最佳答案
我认为今天最好的解决方案是继承 System.Web.Providers(ASP.NET Universal Providers 程序集)中可用的提供者,并简单地为每个公共(public)方法注入(inject)重试策略:
public class MyDefaultProfileProvider : System.Web.Providers.DefaultProfileProvider
{
private RetryPolicy retryPolicy;
public MyDefaultProfileProvider()
{
var retryStrategy = new Incremental(5, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2));
this.retryPolicy = new RetryPolicy<SqlAzureTransientErrorDetectionStrategy>(retryStrategy);
retryPolicy.Retrying += retryPolicy_Retrying;
}
private void retryPolicy_Retrying(object sender, RetryingEventArgs e)
{
// Log, whatever...
}
public override System.Web.Profile.ProfileInfoCollection GetAllProfiles(System.Web.Profile.ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords)
{
int tempTotalRecords = 0;
var profiles = retryPolicy.ExecuteAction(() =>
{
return base.GetAllProfiles(authenticationOption, pageIndex, pageSize, out tempTotalRecords);
});
totalRecords = tempTotalRecords;
return profiles;
}
...
}
要知道重用代码是否合法,您应该 look at the license 。