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

时间:2010-04-16 06:22:20

标签: c# asp.net visual-studio-2005 membership-provider

我创建了自定义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 

我在dbConn事件中实例化了Initialize()个对象。

我的问题是,当SGIMembershipProvider的对象被处理掉时,我怎么能摆脱这个对象。

我知道GC会为我做这一切,但我需要明确地处理掉这个对象。即使我试图覆盖Finalize(),但没有这种可覆盖的方法。我还尝试为SGIMembershipProvider创建析构函数。

任何人都可以为我提供解决方案。

2 个答案:

答案 0 :(得分:2)

从我所看到的情况来看,MembershipProvider不是IDisposable(也不是ProviderBase),所以我们在这里谈论垃圾收集,而不是处理。您应该能够添加自己的终结器(~SGIMembershipProvider() {}),但非托管对象进行通信 - 其他托管毕竟,会收集对象(并且应该处理他们自己的非托管对象,如果有的话 - 很少见)。

答案 1 :(得分:0)

对于这种特定情况,我建议直接在您需要的每个方法中创建数据库连接,而不是存储对它的引用。将其包装在using语句中,让框架为您配置它。

我推荐这种方法的原因是您没有通过挂起该连接对象来保存任何资源。连接池将处理重用现有的打开连接。连接池在非托管代码级别工作。当您关闭/处置托管的Connection对象时,它不一定会关闭物理非托管连接,它只是返回连接池的连接。然后,控制池的非托管代码将确定如何处理它(关闭它,保持打开状态,将其提供给需要它的另一个进程)。同样,当您创建托管连接时,您不一定要从头开始创建新连接,您可能只是重用现有连接。

我确实认为框架需要使这个对象成为一次性的。我可以想到很多其他情况,我希望在提供程序中重用某些东西并最终处理它。