Autofac和MVC整合:每个注册API控制器类型 [英] Autofac and MVC integration: Register Type per API Controller

查看:631
本文介绍了Autofac和MVC整合:每个注册API控制器类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我与.NET 4.5,ASP.NET MVC 5,包的NuGet工作:
Autofac 3.5.2
Autofac ASP.NET网页API 5个积分3.0.0-RC1

我有一个接口,2个不同的实现方式:

 公共类MemoryStreamService:IStreamService {...}
公共类HttpStreamService:IStreamService {...}

此外,通过构造函数注入使用接口的另一具体类:

 公共类MainService:IMainService
{
    公共MainService(IStreamService streamService){...}
}

和我有利用构造函数注入主要服务过2的ASP.NET Web API控制器:

 公共类MemoryStreamController:ApiController
{
    公共MemoryStreamController(IMainService mainService){...}
}公共类HttpStreamController:ApiController
{
    公共HttpStreamController(IMainService mainService){...}
}

我要的是使用MemoryStreamService实现时需要先MemoryStreamController呼叫的情况下被实例化IStreamService的一个实例,当我们在为HttpStreamController呼叫的背景下HttpStreamService实施。

我想实现这一目标通过以下方式在注册范围内的Global.asax.cs的Application_Start()在Autofac建设者的控制器和服务类:

  builder.RegisterType< MainService>()为<&IMainService GT;();builder.RegisterType< MemoryStreamService>()
       。至于< IStreamService>()
       .InstancePerApiControllerType(typeof运算(MemoryStreamController));builder.RegisterType< HttpStreamService>()
       。至于< IStreamService>()
       .InstancePerApiControllerType(typeof运算(HttpStreamController));builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

不过貌似InstancePerApiControllerType()为不工作:我越来越总是IStreamService的第一个实施注册类型为两个控制器(本例中,MemoryStreamController中)

我如何需要配置Autofac在由MemoryStreamController处理请求的情况下获得MemoryStreamService的一个实例,并通过HttpStreamController?

hadled HttpStreamService的呼叫实例

修改:如果我没有使用依赖注入的控制器,这是我会做什么:

 公共类MemoryStreamController:ApiController
{
    公共MemoryStreamController()
    {
        this.mainService =新MainService(新MemoryStreamService());
    }
}公共类HttpStreamController:ApiController
{
    公共HttpStreamController()
    {
        this.mainService =新MainService(新HttpStreamService());
    }
}

所以我的问题可以理解为:我如何可以通过使用Autofac登记我的两个控制器和我的所有服务达到同样


解决方案

我已经按照@TravisIllig建议(感谢!)和:结果
1)用于两个流服务命名注册,结果
2)使用2 MainService命名注册,他们在流服务的类型不同,因为它们可以采取如参数搜索
3)通过指定每个命名MainService适当注册的控制器。

<$p$p><$c$c>builder.RegisterType<MemoryStreamService>().Named<IStreamService>(\"memoryService\");
builder.RegisterType&LT; HttpStreamService&GT;()命名为&lt;&IStreamService GT(HttpService的);建设者
    .RegisterType&LT; MainService&GT;()
    。至于&LT; IMainService&GT;()
    .WithParameter(ResolvedParameter.ForNamed&所述; IStreamService&GT(memoryService))
    .Named&所述; IMainService&GT(mainServiceForMemoryStreams);建设者
    .RegisterType&LT; MainService&GT;()
    。至于&LT; IMainService&GT;()
    .WithParameter(ResolvedParameter.ForNamed&LT; IStreamService&GT;(HttpService的))
    .Named&所述; IMainService&GT(mainServiceForHttpStreams);//这是我注册的API其它控制器
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());//手动注册需要IStreamService的一个特定实例的控制器。
需要被放置在后//这些注册RegisterApiControllers(),以便调用Autofac执行所需注射。
builder.RegisterType&LT; MemoryStreamController&GT;()
       .WithParameter(ResolvedParameter.ForNamed&所述; IMainService&GT(mainServiceForMemoryStreams));
builder.RegisterType&LT; HttpStreamController&GT;()
       .WithParameter(ResolvedParameter.ForNamed&所述; IMainService&GT(mainServiceForHttpStreams));

I'm working with .Net 4.5, ASP.NET MVC 5, and the NuGet packages: Autofac 3.5.2 Autofac ASP.NET Web Api 5 Integration 3.0.0-rc1

I have 2 different implementations of an interface:

public class MemoryStreamService : IStreamService { ... }
public class HttpStreamService : IStreamService { ... }

Also another concrete class that uses the interface by constructor injection:

public class MainService : IMainService 
{
    public MainService(IStreamService streamService) { ... }
}

And I have 2 ASP.NET Web API Controllers using the main service by constructor injection too:

public class MemoryStreamController : ApiController 
{
    public MemoryStreamController(IMainService mainService) { ... }
}

public class HttpStreamController : ApiController 
{
    public HttpStreamController(IMainService mainService) { ... }
}

What I want is to use the MemoryStreamService implementation when an instance of IStreamService need to be instantiated in the context of a call to MemoryStreamController, and the HttpStreamService implementation when we are in the context of a call to the HttpStreamController.

I'm trying to accomplish that by registering the controllers and service classes in Autofac builder at Application_Start() within Global.asax.cs in the following way:

builder.RegisterType<MainService>().As<IMainService>();

builder.RegisterType<MemoryStreamService>()
       .As<IStreamService>()
       .InstancePerApiControllerType(typeof(MemoryStreamController));

builder.RegisterType<HttpStreamService>()
       .As<IStreamService>()
       .InstancePerApiControllerType(typeof(HttpStreamController));

builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

But looks like the InstancePerApiControllerType() does not work for that: I'm getting always the first registered implementation Type of the IStreamService (in this sample, MemoryStreamController) for both Controllers.

How do I need to configure Autofac for getting an instance of MemoryStreamService in the context of a request handled by MemoryStreamController, and an instance of HttpStreamService for calls hadled by HttpStreamController?

EDIT: If I weren't using dependency injection for the controllers, this is what I would do:

public class MemoryStreamController : ApiController 
{
    public MemoryStreamController() 
    {
        this.mainService = new MainService(new MemoryStreamService());
    }
}

public class HttpStreamController : ApiController 
{
    public HttpStreamController()
    {
        this.mainService = new MainService(new HttpStreamService());
    }
}

So my question can be read as: How can I achieve the same by using Autofac for registering both my controllers and all my services?

解决方案

I've followed @TravisIllig advice (thanks!) and:
1) used named registrations for both "stream services",
2) used 2 named registrations for MainService, they differ in the type of stream service they can take as parameter
3) registered the controllers by specifying each named MainService as appropriate.

builder.RegisterType<MemoryStreamService>().Named<IStreamService>("memoryService");
builder.RegisterType<HttpStreamService>().Named<IStreamService>("httpService");

builder
    .RegisterType<MainService>()
    .As<IMainService>()
    .WithParameter(ResolvedParameter.ForNamed<IStreamService>("memoryService"))
    .Named<IMainService>("mainServiceForMemoryStreams");

builder
    .RegisterType<MainService>()
    .As<IMainService>()
    .WithParameter(ResolvedParameter.ForNamed<IStreamService>("httpService"))
    .Named<IMainService>("mainServiceForHttpStreams");

// This is for registering the other controllers of my API
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

// Manually registers controllers that need an specific instance of IStreamService.
// These registrations needs to be placed after the "RegisterApiControllers()" call in order to Autofac to perform the desired injections.
builder.RegisterType<MemoryStreamController>()
       .WithParameter(ResolvedParameter.ForNamed<IMainService>("mainServiceForMemoryStreams"));
builder.RegisterType<HttpStreamController>()
       .WithParameter(ResolvedParameter.ForNamed<IMainService>("mainServiceForHttpStreams"));

这篇关于Autofac和MVC整合:每个注册API控制器类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆