如何在自定义成员资格提供程序中处理自定义对象

3

我已经创建了自定义的MembershipProvider。在此提供程序中,我使用了类DBConnect的一个实例来处理数据库功能。请查看下面的代码:

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创建析构函数。

有人能给我提供解决方案吗?

2个回答

2
据我所见,MembershipProvider 不是 IDisposableProviderBase 也不是),因此我们正在谈论垃圾回收,而不是处理。你应该能够添加自己的终结器(~SGIMembershipProvider() {}),但那只能与 非托管 对象通信 - 其他 托管 对象同样会被收集,毕竟(如果有的话)它们应该处理自己的非托管对象 - 这种情况很少见。

谢谢Marc!就像我说的那样,我也创建了自己的终结器~SGIMembershipProvider() {}。它会被执行吗? - IrfanRaza
@IrfanRaza - 是的,当它被垃圾回收时。如果没有被调用,那么可能引擎会在整个过程中保持单个提供程序。 - Marc Gravell
有没有其他更好的方法? - IrfanRaza

0
针对这种情况,我建议直接在需要使用它的每个方法中创建数据库连接,而不是存储引用。将其包装在using语句中,让框架为您处理它的释放。
我推荐这种方法的原因是,保留连接对象并不能节省任何资源。连接池会处理重用现有打开的连接。连接池在非托管代码级别上工作。当您关闭/处理托管连接对象时,它并不一定会关闭物理未管理的连接,它只是将连接返回到连接池。控制池的非托管代码将确定如何处理它(关闭它,保持它打开一段时间,将其提供给需要它的另一个进程)。同样,当您创建托管连接时,您并不一定是从头开始创建新连接,您可能只是重新使用现有连接。
但我认为框架需要使这个对象可处理。我可以想到很多其他情况,在这些情况下,我想重用提供程序中的某些内容,并在最后处理它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接