2014-10-09 36 views
3

我想向我的asp mvc頁面添加一個容易訪問的幫助類。我創建了一個名爲存儲庫的類。它有一個靜態屬性「當前」,它具有以下功能:這是其中的一個循環引用嗎?

public static readonly Repositories Current 
{ 
    get 
    { 
     if(HttpContext.Current.Items["Repositories"] == null) 
      HttpContext.Current.Items["Repositories"] = new Repositories(HttpContext.Current); 
     return (Repositories)HttpContext.Current.Items["Repositories"]; 
    } 
} 

的一點是,類有使用類的當前實例靜態輔助功能(依賴於當前的HttpContext)。輔助函數完成各種工作,我想這樣組織它的原因是因爲它使控制器中的外觀更好看,並且我有可能訪問所有數據庫存儲庫(實際的句柄對象只有在訪問儘管如此)。

無論如何,正如你所看到的,構造函數需要一個HttpContext作爲參數,然後將其存儲在私有類字段中,這樣我就可以輸入更少的內容。這意味着Repositories類實例引用了HttpContext類實例,反之亦然。當HttpContext被丟棄時,這是否意味着它仍然存在於內存中,由存儲庫實例的循環引用保存?

+1

您希望何時刪除HttpContext? – 2014-10-09 12:32:40

+3

除了你的問題,你在這裏做的只是引入_global variables_。 如果我是你,我會強烈避免這樣的設計:它會導致無法測試的代碼。 您應該通過構造函數將您的存儲庫注入控制器,而不是使用HttpContext來檢索它們。 – 2014-10-09 12:34:37

+0

它不是全球性的,但如果每個請求的輔助類是實例化的,還是它?我嘗試了整個噴射的事情,但它太笨重了,我不喜歡。 – user81993 2014-10-09 13:00:24

回答

2

「孤立的」循環引用不會強制對象留在內存中。

如果你這樣做:

class A 
{ 
    public B b; 

    ~A() 
    { 
     Console.WriteLine("COLLECTED A!"); 
    } 
} 

class B 
{ 
    public A a; 

    ~B() 
    { 
     Console.WriteLine("COLLECTED B!"); 
    } 
} 

,並運行此代碼:

var a = new A(); 
var b = new B(); 

a.b = b; 
b.a = a; 

a = null; 
b = null; 

GC.Collect(); 

這兩種情況都可以(並且會)被垃圾收集。您將得到類似於以下輸出的內容:

COLLECTED B! 
COLLECTED A!