Autofac和MVC整合:注册每API控制器类型(Autofac and MVC integrat

2019-10-21 10:56发布

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

我有一个接口的两个不同的实施方式中:

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

还使用由构造注入用界面的另一个具体类:

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

我有使用构造器注入的主要服务过2个的ASP.NET Web API控制器:

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

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

我想是使用MemoryStreamService执行时需要先MemoryStreamController呼叫的情况下被实例化IStreamService的一个实例,以及HttpStreamService实现当我们在对一HttpStreamController调用的上下文。

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

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());

但看起来像InstancePerApiControllerType()为不工作:我得到总是IStreamService的第一个注册的实现类型两个控制器(本例中,MemoryStreamController中)。

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

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

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

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

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

Answer 1:

这个怎么样。 首先您注册服务,命名为:

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

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

然后你注册一个FUNC工厂,可以解决基于名字的正确服务。 像这样:

builder.Register<Func<string, IStreamService>>(c =>
        {
            var context = c.Resolve<IComponentContext>();
            return service =>
            {
                return context.ResolveNamed<IStreamService>(service);
            };
        });

然后在控制器当你解决IMainService你可以注入一个Func<string, IMainService>在构造为第一个参数MainService必须是字符串)。 这样,你可以沿着你想解决服务的名称通过。 像这样:

public class MemoryStreamController : ApiController 
{
    private IMainService _service;

    public MemoryStreamController(Func<string, IMainService> mainService) 
    {
        _service = mainService("MemoryStreamService")
    }
}

然后在构造函数MainService你调用FUNC工厂被注射的类型名称。 像这样:

public MainService(string type, Func<string, IStreamService> factory)
{
    _service = factory(type);
} 


Answer 2:

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

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 and MVC integration: Register Type per API Controller