2010-04-16 51 views
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

從我所看到的,MembershipProvider不是IDisposable(也不是ProviderBase),所以我們真的在談論垃圾收集在這裏,而不是處置。您應該能夠添加自己的終結(~SGIMembershipProvider() {}),但應該談話非託管對象 - 其他管理對象將收集,畢竟(也應該處理好自己的非託管對象,如果有的話 - 這很少見)。

+0

謝謝馬克!正如我所說,我也創建了自己的終結器〜SGIMembershipProvider(){}。這是否會被執行? – IrfanRaza 2010-04-16 10:44:03

+0

@IrfanRaza - 是的;當它被垃圾收集時。如果它沒有被調用,那麼引擎在這段時間內可能會保持一個提供者。 – 2010-04-16 10:50:32

+0

還有其他更好的方法嗎? – IrfanRaza 2010-04-16 11:23:30

0

對於這個特定的場景,我建議直接在你需要的每個方法裏面創建你的數據庫連接,而不是存儲對它的引用。將它封裝在一個使用語句中,並讓框架爲您處置它。

我推薦這種方法的原因是您沒有通過掛接到該連接對象來保存任何資源。連接池將爲您處理重複使用現有的開放連接。連接池適用於非託管代碼級別。當您關閉/處理受管理的連接對象時,它不一定關閉物理非連接的連接,它只是將連接返回到連接池。控制池的非託管代碼將決定如何處理它(關閉它,保持打開狀態,並將其提供給需要它的另一個進程)。同樣,當您創建託管連接時,您不一定從頭創建新連接,您可能只是重用現有連接。

我認爲框架需要使這個對象一次性使用。我可以想到很多其他情況,我希望在提供程序中重用某些內容並最終處理它。