2016-02-18 97 views
1

我有一個使用StructureMap的ASP.NET MVC應用程序。StructureMap和HTTP請求範圍的服務 - 爲什麼我的服務在單一範圍內創建兩次?

我已經創建了一個名爲SecurityContext的服務,它具有靜態Current屬性。一個簡化的版本是這樣的:

public class SecurityContext : ISecurityContext 
{ 
    public bool MyProperty { get; private set; } 

    public static SecurityContext Current 
    { 
     get 
     { 
      return new SecurityContext() { MyProperty = true }; 
     } 
    } 
} 

我已經在我的StructureMap註冊表如下迷上這件事:

For<ISecurityContext>().Use(() => SecurityContext.Current); 

我的使用方法,這個LINQ表達式超載的理解是,返回的具體對象對於整個HTTP請求範圍是相同的。

但是,我設置了一個測試用例,其中我的上下文接口在兩個位置注入,一次在控制器的構造函數中,並且在我的視圖繼承的基類中再次使用SetterProperty屬性。

當調試時,我觀察到Current靜態方法被擊中兩次,所以我的假設是錯誤的。任何人都可以糾正我在這裏做什麼?我想要這個請求範圍的原因是因爲我從數據庫中將某些數據加載到我的上下文類中,所以我不希望這種情況在給定頁面加載時發生多次。

在此先感謝。

回答

4

配置的默認生命週期是Transient,因此每個ISecurityContext請求都會創建一個SecurityContext的新實例。我想你想要的是使用傳統的HttpContext生命週期。

包含StructureMap.Web nuget包。然後改變你的配置如下:上lifecyles

For<ISecurityContext>() 
    .Use(() => SecurityContext.Current) 
    .LifeCycleIs<HttpContextLifecycle>(); 

更多信息,可以發現here

HttpContextLifecycle已過時,但我不知道它是否或何時會被刪除。 StructureMap團隊建議不要使用這個較老的ASP.Net生命週期。他們在文檔中聲明,大多數現代Web框架使用每個請求的嵌套容器來完成相同的範圍。有關嵌套容器的信息可以在here找到。

我不知道你使用的ASP.Net MVC的版本是否被認爲是一個現代的web框架。我懷疑這是因爲ASP.Net Core 1.0真的是ASP.Net系列中的第一個完全支持DI的使用。不過,我會推遲到@jeremydmiller這一個。

+0

加上從StructureMap作者(我) –

+0

謝謝你們。作品一種享受。我可以問,當你說'傳統'時,這是否意味着HttpContext生命週期將會過時?如果是這樣,將使用什麼? – getsetcode