C# IoC:程序集之间的依赖项注入和总体实例
我听说这应该是可能的,但我无法想象这应该如何运作 我正在为我的项目使用依赖注入(autofac)。我和其他人一起开发一个项目,并调用他的类的方法(我使用他的程序集) 然后我得到一个对象的实例,其他人应该使用它进行操作。 我们希望避免在每个方法上传递此对象实例,并使用autofac 他是否可以在不传递任何参数的情况下在组装项目中解析此实例? 我想我们至少要通过DI容器。。。但是我听说依赖注入的概念应该使您能够在整个“执行上下文”中解析对象并得到相同的对象 以下是asp.net web api的示例: 这是asp.net webapi项目的api控制器:C# IoC:程序集之间的依赖项注入和总体实例,c#,dependency-injection,ioc-container,autofac,service-locator,C#,Dependency Injection,Ioc Container,Autofac,Service Locator,我听说这应该是可能的,但我无法想象这应该如何运作 我正在为我的项目使用依赖注入(autofac)。我和其他人一起开发一个项目,并调用他的类的方法(我使用他的程序集) 然后我得到一个对象的实例,其他人应该使用它进行操作。 我们希望避免在每个方法上传递此对象实例,并使用autofac 他是否可以在不传递任何参数的情况下在组装项目中解析此实例? 我想我们至少要通过DI容器。。。但是我听说依赖注入的概念应该使您能够在整个“执行上下文”中解析对象并得到相同的对象 以下是asp.net web 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;
}
}
公共类文档控制器:ApiController
{
//获取/api/documents
公共HttpResponseMessage Get()
{
//这里我调用另一个开发者的方法,
//安全/授权应在
//他的方法!
//在此上下文中,WebAPI提供了
//此域中当前用户的IPrincipal
//变量=>“HttpContext.Current.User”,但我们
//不想在每次方法调用时都传递它
ClassFromOtherAssembly.GetDocuments();
HttpResponseMessage响应=
Request.CreateResponse(
HttpStatusCode.OK,文档);
返回响应;
}
}
这是另一个开发人员的类。他应交付文件,并检查用户是否获得授权:
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
}
}
}
otherassembly中的公共类
{
公共列表文件()
{
//安全检查
i主要负责人=
DI_容器解析(IPrincipal);
if(委托人IsInRole(“管理”))
{
//返回列表
}
其他的
{
//返回空列表
}
}
}
您通过直接从GetDocuments()调用Resolve来使用ServiceLocator(反模式)
使用带构造函数注入的控制反转通过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
}
}
}
otherassembly中的公共类
{
私人知识产权主体;
来自其他程序集的公共类(i主要负责人)
{
this.principal=principal;
}
公共列表文件()
{
//安全检查
if(委托人IsInRole(“管理”))
{
//返回列表
}
其他的
{
//返回空列表
}
}
}
您通过直接从GetDocuments()调用Resolve来使用ServiceLocator(反模式)
使用带构造函数注入的控制反转通过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
}
}
}
otherassembly中的公共类
{
私人知识产权主体;
来自其他程序集的公共类(i主要负责人)
{
this.principal=principal;
}
公共列表文件()
{
//安全检查
if(委托人IsInRole(“管理”))
{
//返回列表
}
其他的
{
//返回空列表
}
}
}
不,不要通过容器本身,您将得到一个服务定位器模式,如果您快速搜索,您将了解此模式有一种腐烂的气味
public class Foo
{
private IContainer container;
private IBar bar;
public Foo( IContainer container) //no-no
{
this.container = container;
this.bar = container.Resolve<IBar>();
}
}
类型在哪个程序集中并不重要。这就是IoC和DI的全部要点——将应用程序的各个部分解耦,使您依赖于抽象,而不是具体的实现
编辑
您误解了DI的服务定位器模式。“我们希望使用依赖注入而不是传递参数”-传递参数是DI,相反,从静态容器解析类型是服务定位器
public class DocumentsController : ApiController
{
public HttpResponseMessage Get()
{
ClassFromOtherAssembly.GetDocuments(); //this is Service locator
//really bad for testability and maintenance
...
}
}
我看起来像这样
public class DocumentsController : ApiController
{
private IDocumentProvider;
public DocumentsController(IDocumentProvider provider)
{
this.provider = provider;
}
public HttpResponseMessage Get()
{
provider.GetDocuments(); //this is DI
...
}
}
不,不要通过容器本身,您将得到一个服务定位器模式,如果您快速搜索,您将了解此模式有一种腐烂的气味
public class Foo
{
private IContainer container;
private IBar bar;
public Foo( IContainer container) //no-no
{
this.container = container;
this.bar = container.Resolve<IBar>();
}
}
类型在哪个程序集中并不重要。这就是IoC和DI的全部要点——将应用程序的各个部分解耦,使您依赖于抽象,而不是具体的实现
编辑
您误解了DI的服务定位器模式。“我们希望使用依赖注入而不是传递参数”-传递参数是DI,相反,从静态容器解析类型是服务定位器
public class DocumentsController : ApiController
{
public HttpResponseMessage Get()
{
ClassFromOtherAssembly.GetDocuments(); //this is Service locator
//really bad for testability and maintenance
...
}
}
我看起来像这样
public class DocumentsController : ApiController
{
private IDocumentProvider;
public DocumentsController(IDocumentProvider provider)
{
this.provider = provider;
}
public HttpResponseMessage Get()
{
provider.GetDocuments(); //this is DI
...
}
}
不,我不想使用ServiceLocator模式。计划是不通过任何物体。甚至在构造函数中也没有。该类将按时创建,并从不同的方法调用(不同的用户和iPrincipal)中使用,而不是传递我们希望使用依赖注入的参数,以便他获得所需的对象。“服务定位器”的另一个好名称是“依赖提取”,而不是“依赖注入”:-)不,我不想使用ServiceLocator模式。计划是不通过任何物体。甚至在构造函数中也没有。该类将按时创建,并从不同的方法调用(不同的用户和iPrincipal)中使用,而不是传递我们希望使用依赖注入的参数,以便他获得所需的对象。“服务定位器”的另一个好名字是“依赖提取”,而不是“依赖注入”:-)