将具有不同配置的服务注入控制器

时间:2016-07-15 09:34:02

标签: asp.net-web-api dryioc

在Web API应用程序中,我有两个控制器,MyAController和MyBController,每个控制器都依赖于IMyService但具有不同的配置:

public class MyAController : ApiController
{
    private readonly IMyService service;
    public MyAController(IMyService service)
    {
        this.service = service;
    }
}

public class MyBController : ApiController
{
    private readonly IMyService service;
    public MyBController(IMyService service)
    {
        this.service = service;
    }
}

public interface IMyService
{
}

public class MyService : IMyService
{
    private readonly string configuration;
    public MyService(string configuration)
    {
        this.configuration = configuration;
    }
}

我尝试过以下方式配置DryIoc:

private enum ServiceKeyEnum
{
    ServiceA,
    ServiceB
}

container.RegisterInstance("configurationA", serviceKey: "CONFIGURATIONA");
container.RegisterInstance("configurationB", serviceKey: "CONFIGURATIONB");
container.Register<IMyService, MyService>(Reuse.Singleton, Made.Of(() => new MyService(Arg.Of<string>("CONFIGURATIONA"))), serviceKey: ServiceKeyEnum.ServiceA);
container.Register<IMyService, MyService>(Reuse.Singleton, Made.Of(() => new MyService(Arg.Of<string>("CONFIGURATIONB"))), serviceKey: ServiceKeyEnum.ServiceB);

container.Register<MyAController>(Reuse.InResolutionScope, made: Parameters.Of.Details((r, p) => ServiceDetails.IfUnresolvedReturnDefault).Type<IMyService>(serviceKey: ServiceKeyEnum.ServiceA));
container.Register<MyBController>(Reuse.InResolutionScope, made: Parameters.Of.Details((r, p) => ServiceDetails.IfUnresolvedReturnDefault).Type<IMyService>(serviceKey: ServiceKeyEnum.ServiceB));

如果我尝试使用以下方式调用resolve:

var controllerA = container.Resolve<MyAController>();
var controllerB = container.Resolve<MyBController>();

我得到两个分别配置了configurationA和configurationB的控制器。 但是,当我尝试使用REST调用来调用api时,我收到以下错误:

An error occurred when trying to create a controller of type 'MyAController'. Make sure that the controller has a parameterless public constructor.

所以我想,我需要以不同的方式注册控制器...但是如何?

任何帮助都将非常感谢....

1 个答案:

答案 0 :(得分:0)

错误是由控制器设置不当引起的。 DryIoc.WebApi扩展已经发现并注册了您的控制器,因此通常您不需要自己动手。我将在稍后为您提供特定设置的工作代码(来自问题评论)。但现在“无参数构造函数......”背后的原因:当DryIoc失败时,WebAPI回退到使用Activator.CreateInstance作为控制器,它需要无参数构造函数。回退掩盖了原始的DryIoc错误。要找到它,您可以将DryIoc.WebApi扩展名设置为:

container = container.WithWebApi(throwIfUnresolved: type => type.IsController());

您的案例的工作设置,它使用条件注册依赖项以选择注入控制器:

container.Register<IMyService, MyService>(Made.Of(
    () => new MyService(Arg.Index<string>(0)), _ => "configurationA"),  
    Reuse.Singleton, 
    setup: Setup.With(condition:  r => r.Parent.ImplementationType == typeof(MyAController)));

container.Register<IMyService, MyService>(Made.Of(
    () => new MyService(Arg.Index<string>(0)), _ => "configurationB"),  
    Reuse.Singleton, 
    setup: Setup.With(condition:  r => r.Parent.ImplementationType == typeof(MyBController)));

此设置主要不需要特殊的控制器注册。

另外,您可以避免使用服务密钥,而无需单独注册配置字符串。