簡體   English   中英

IoC:程序集之間的依賴注入和整體實例

[英]IoC: Dependency Injection and overall instances between assemblies

我聽說這應該可行,但是我無法想象這應該如何工作。

我在我的項目中使用依賴注入(autofac)。 我與其他人一起開發一個項目,並調用他的類的方法(我使用他的程序集)。

然后,我得到另一個人應該用於其操作的對象的實例。 我們希望避免在每種方法上都傳遞此對象實例,而應使用autofac。

他可以在不傳遞任何參數的情況下在裝配項目中解析此實例嗎? 我認為我們至少必須通過DI容器...但是我聽說依賴注入的概念應該使您有可能可以在整個“執行上下文”中解析對象並獲得相同的對象。

這是asp.net Web 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
        }
    }
}

不,不要通過容器本身,您將得到“ 服務定位器”模式,如果進行快速搜索,您將了解到這種模式有腐爛的味道。

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誤解了服務定位器模式。 “而不是傳遞參數,我們要使用依賴注入”-傳遞參數是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 ... } } 

您通過直接從GetDocuments()調用Resolve來使用ServiceLocator(反模式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
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM