2013-11-27 56 views
0

我有一個asp.net應用程序。我正在使用單例模式來設計我的代碼。看起來像下面...asp.net中的單例模式

public static class FactoryClass 
    { 
     private static Core obj = null; 
     private static readonly object padLock = new object(); 
     public static Core GetInstance() 
     { 
      lock (padLock) 
      { 
       if (obj == null) 
       { 
        obj = new Core(); 
       } 
      } 
      return obj; 
     } 
    } 

此實現是線程安全的。我想知道這個實現是否正確,在asp.net的情況下(多個請求將共享單個實例)。請指教...

+3

參見http://csharpindepth.com/articles/general/singleton.aspx –

+2

你在asp.net中創建一個靜態單例的原因是什麼?這個班會有特別貴的東西嗎? –

+0

您是否缺少私有構造函數? –

回答

0

單個對象作用域將位於應用程序域內,這意味着所有會話都將使用該appdomain內的SingleTon對象(bydefault)。

僅當您的服務器場具有不同的服務器時,纔會創建一個新對象。

我更喜歡只在需要構建對象時鎖定,而不是在需要返回時鎖定。以下是修改後的代碼:

public static class FactoryClass 
{ 
    private static Core obj = null; 
    private static readonly object padLock = new object(); 

    public static Core GetInstance() 
    { 
     lock (padLock) 
     { 
      if (obj == null) 
      { 
       obj = new Core(); 
      } 
     } 
     return obj; 
     } 
} 
+0

什麼是在單身模式中使用私人構造函數? – JIKKU

+0

我已經更改了代碼,我得到了你需要單核對象而不是工廠類。 –

+2

此實現不是線程安全的,因爲它不能確保null測試和構造函數調用之間的原子性。你可以看看http://csharpindepth.com/articles/general/singleton.aspx,正如@HansKesting指出的那樣 – jbl

0

它取決於Core類型的對象中存儲了什麼類型的數據。說它的一些配置數據,你想單獨管理(即它與web.config中的完全不同),那麼它是有道理的。

然而,讓我們說,如果網站是一個購物車應用程序...並且您希望存儲這樣的用戶對象......假設用戶對象包含他已在卡中保存的項目列表。這將存儲在appdomain中。因此它違背了你的實現。因爲您希望將用戶信息與傳入請求綁定,而不是整個應用程序。因此,每次請求您至少需要查詢一次...(以傳統意義上講)。

繼續使用相同的例子,想象一下你想以這種方式使用用戶對象:這個用戶對象被用在你的web應用程序中不同類的內部。傳統上,人們會編寫代碼來訪問數據庫,並在每次需要使用用戶對象時創建對象。相反,你會想要一些單例模式。在這種情況下,您的用戶對象將從db中查詢(並創建)一次,並在請求的整個生命週期中重新使用。如果你將這個對象(在其創建後)緩存在http上下文緩存中,這是可能的。 HttpContext.Current.Items["foo"]

下面的代碼說明了點...

public class AppUser 
{ 
    public string Username { get; set; } 
    public string[] Roles { get; set; } 

    public AppUser() 
    { 
     var appuser = HttpContext.Session["AppUser"] as AppUser; 
     if(appuser == null) 
      throw new Exception("User session has expired"); 
     Username = appuser.Username; 
     Roles = appuser.Roles; 
    } 
} 


public class WebAppContext 
{ 
    const string ContextKey = "WebAppContext"; 

    WebAppContext() { } //empty constructor 
    public static WebAppContext Current 
    { 
     get 
     { 
      var ctx = HttpContext.Current.Items[ContextKey] as WebAppContext; 
      if(ctx == null) 
      { 
       try 
       { 
        ctx = new WebAppContext() { User = new AppUser() }; 
       } 
       catch 
       { 
        //Redirect for login 
       } 
       HttpContext.Current.Items.Add(ContextKey, ctx);      
      }  
      return ctx;  
     } 
    } 

    public AppUser User { get; set; } 
} 

PS:這個職位採取:a request level singleton object in asp.net

+0

@deostoll您提到的代碼是針對每個用戶的單個實例。我詢問了多個用戶訪問同一個實例 – JIKKU

+0

@anish我已經給出了一個站點範圍配置設置的示例場景(與web.config中的配置設置完全不同)。例如。這樣的設置可以用於例如您的網站的橫幅圖像。圖像路徑可以設置在應用程序級變量(在你的情況下是一個靜態變量) – deostroll