2

我聽到這應該是可能的,但我無法想象這應該如何工作。IoC:依賴注入和程序集之間的整體實例

我爲我的項目使用了依賴注入(autofac)。我和別人一起開發一個項目,並且調用他的課程方法(我使用他的程序集)。

然後我得到一個對象的實例,其他人應該使用他的操作。 我們希望避免在每個方法上傳遞此對象實例並使用autofac。

他可以在他的裝配項目中解析這個實例而不傳遞任何參數嗎? 我認爲我們必須至少通過DI容器......但是我聽說依賴注入的概念應該可以讓你可以在整個「執行上下文」中解析對象並獲得相同的結果。

這裏是與asp.net網頁API的一個示例:

這是一個asp.net的WebAPI項目的API控制器:

public class DocumentsController : ApiController 
{ 
    // GET /api/documents 
    public HttpResponseMessage Get() 
    { 
     // Here I call the method of the other developer, 
     // security/authorization should be handled in 
     // his method! 
     // In this context the WebAPI provides the 
     // IPrincipal of the current user in this 
     // variable => "HttpContext.Current.User" but we 
     // don't want to pass it on every method call 
     ClassFromOtherAssembly.GetDocuments(); 

     HttpResponseMessage response = 
      Request.CreateResponse<IEnumerable<Document>>(
       HttpStatusCode.OK, documents); 

     return response; 
    } 
} 

這是類的其它顯影劑。他應該提供的文件,並檢查用戶是否被授權:

public class ClassFromOtherAssembly 
{ 
    public List<Documents> GetDocuments() 
    { 
     //Security check 
     IPrincipal principal = 
      DI_Container.Resolve(IPrincipal); 

     if(principal.IsInRole("Admin")) 
     { 
      //return the list 
     } 
     else 
     { 
      //return empty list 
     } 
    } 
} 

回答

3

不,不通過容器本身,你會最終有一個服務定位圖案,如果你做一個快速的搜索,你會understan d這種模式有一種腐爛的氣味。

public class Foo 
{ 
    private IContainer container; 
    private IBar bar; 

    public Foo(IContainer container) //no-no 
    { 
     this.container = container; 
     this.bar = container.Resolve<IBar>(); 
    } 
} 

而是使用正確的DI,像

public class Foo 
{ 
    private IBar bar; 

    public Foo(IBar bar) 
    { 
     this.bar = bar; 
    } 
} 

這並不重要,在裝配的類型。這是IoC和DI的重點 - 將應用程序的各個部分分離開來,並使您依賴抽象而不是具體的實現。


編輯
與DI你誤會Service Locator模式。 「而不是傳遞一個參數,我們想使用依賴注入」 - 傳遞一個參數是一個DI,相比之下,從靜態容器解析類型是一個服務定位器。

public class DocumentsController : ApiController 
{ 
    public HttpResponseMessage Get() 
    { 
     ClassFromOtherAssembly.GetDocuments(); //this is Service locator 
     //really bad for testability and maintenance 
     ... 
    } 
} 

DI看起來像這樣

public class DocumentsController : ApiController 
{ 
    private IDocumentProvider; 

    public DocumentsController(IDocumentProvider provider) 
    { 
     this.provider = provider; 
    } 

    public HttpResponseMessage Get() 
    { 
     provider.GetDocuments(); //this is DI 
     ... 
    } 
} 
+0

不,我不想用的ServiceLocator模式。該計劃不是要傳遞任何對象。甚至不在構造函數中。該類將按時創建,並將用於不同的方法調用(使用不同的用戶和IPrincipals)而不是傳遞我們想要使用依賴注入的參數,以便他得到他需要的對象。 – user437899 2012-07-06 09:57:50

+0

@ user437899請參閱我的編輯。希望它是有道理的。 – oleksii 2012-07-06 10:24:16

+1

「服務定位器」的另一個好名字是與「依賴注入」相對的「依賴提取」:-) – Steven 2012-07-06 11:30:57

1

你正在使用的服務定位器(反模式),通過直接從GetDocuments()

器的使用反轉呼籲解決與構造函數注入傳遞在IPrinciple這樣:

public class ClassFromOtherAssembly 
{ 
    private IPrincipal principal; 

    public ClassFromOtherAssembly(IPrincipal principal) 
    { 
     this.principal = principal; 
    } 

    public List<Documents> GetDocuments() 
    { 
     //Security check 
     if (principal.IsInRole("Admin")) 
     { 
      //return the list 
     } 
     else 
     { 
      //return empty list 
     } 
    } 
}