繁体   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