C# 如何从自定义成员资格提供程序中处置自定义对象
我已经创建了我的自定义会员资格提供商。我在这个提供程序中使用了DBConnect类的一个实例来处理数据库函数。请看下面的代码:C# 如何从自定义成员资格提供程序中处置自定义对象,c#,asp.net,visual-studio-2005,membership-provider,C#,Asp.net,Visual Studio 2005,Membership Provider,我已经创建了我的自定义会员资格提供商。我在这个提供程序中使用了DBConnect类的一个实例来处理数据库函数。请看下面的代码: public class SGIMembershipProvider : MembershipProvider { #region "[ Property Variables ]" private int newPasswordLength = 8; private string connectionString; private str
public class SGIMembershipProvider : MembershipProvider
{
#region "[ Property Variables ]"
private int newPasswordLength = 8;
private string connectionString;
private string applicationName;
private bool enablePasswordReset;
private bool enablePasswordRetrieval;
private bool requiresQuestionAndAnswer;
private bool requiresUniqueEmail;
private int maxInvalidPasswordAttempts;
private int passwordAttemptWindow;
private MembershipPasswordFormat passwordFormat;
private int minRequiredNonAlphanumericCharacters;
private int minRequiredPasswordLength;
private string passwordStrengthRegularExpression;
private MachineKeySection machineKey;
**private DBConnect dbConn;**
#endregion
.......
public override bool ChangePassword(string username, string oldPassword, string newPassword)
{
if (!ValidateUser(username, oldPassword))
return false;
ValidatePasswordEventArgs args = new ValidatePasswordEventArgs(username, newPassword, true);
OnValidatingPassword(args);
if (args.Cancel)
{
if (args.FailureInformation != null)
{
throw args.FailureInformation;
}
else
{
throw new Exception("Change password canceled due to new password validation failure.");
}
}
SqlParameter[] p = new SqlParameter[3];
p[0] = new SqlParameter("@applicationName", applicationName);
p[1] = new SqlParameter("@username", username);
p[2] = new SqlParameter("@password", EncodePassword(newPassword));
bool retval = **dbConn.ExecuteSP("User_ChangePassword", p);**
return retval;
} //ChangePassword
public override void Initialize(string name, NameValueCollection config)
{
if (config == null)
{
throw new ArgumentNullException("config");
}
......
ConnectionStringSettings ConnectionStringSettings = ConfigurationManager.ConnectionStrings[config["connectionStringName"]];
if ((ConnectionStringSettings == null) || (ConnectionStringSettings.ConnectionString.Trim() == String.Empty))
{
throw new ProviderException("Connection string cannot be blank.");
}
connectionString = ConnectionStringSettings.ConnectionString;
**dbConn = new DBConnect(connectionString);
dbConn.ConnectToDB();**
......
} //Initialize
......
} // SGIMembershipProvider
我在Initialize()
事件中实例化了dbConn
对象
我的问题是,当SGIMembershipProvider
的对象被处理掉时,如何处理掉这个对象
我知道GC会为我完成这一切,但我需要显式地处理该对象。甚至我也尝试重写Finalize()
,但没有这样的可重写方法。我还尝试为SGIMembershipProvider
创建析构函数
有人能给我提供解决方案吗。据我所知,它不可
IDisposable
(也不可),所以我们这里真正谈论的是垃圾收集,而不是处理。您应该能够添加自己的终结器(~SGIMembershipProvider(){}
),但该终结器应该只与非托管对象对话-毕竟,其他托管对象也将被收集(并且应该处理它们自己的非托管对象,如果有的话,这是罕见的)。对于此特定场景,我建议直接在您需要的每个方法中创建DB连接,而不是存储对它的引用。将它包装在using语句中,让框架为您处理它
我推荐这种方法的原因是,您不会因为挂起连接对象而节省任何资源。连接池将为您处理现有打开连接的重用。连接池在非托管代码级别工作。当您关闭/处置托管连接对象时,它不一定关闭物理非托管连接,它只是将连接返回到连接池。然后,控制池的非托管代码将决定如何处理它(关闭它,保持它打开一段时间,将它提供给另一个需要它的进程)。同样,当您创建托管连接时,不一定是从头开始创建新连接,您可能只是在重用现有连接
我确实认为框架需要使这个对象成为一次性的。我可以想到很多其他情况,在这些情况下,我希望重用提供者中的某些内容,并最终将其处理。谢谢Marc!正如我所说,我还创建了自己的终结器~SGIMembershipProvider(){}。这会被处决吗?@IrfanRaza-是的;当它被垃圾收集时。如果它没有被调用,那么引擎可能会在整个过程中保留一个提供程序。还有其他更好的方法吗?