Asp.net web api 将不同配置的服务注入控制器

Asp.net web api 将不同配置的服务注入控制器,asp.net-web-api,dryioc,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; }

在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));
所以我想,我需要以不同的方式注册控制器。。。但是怎么做呢


如有任何帮助,将不胜感激。…

此错误是由控制器设置不当引起的。DryIoc.WebApi扩展已经发现并注册了您的控制器,所以通常您不需要自己完成。稍后,我将为您提供特定设置的工作代码(来自问题注释)。但现在,“无参数构造函数…”背后的原因是:当DryIoc失败时,WebAPI会退回到使用
Activator.CreateInstance
作为控制器,这需要无参数构造函数。回退会掩盖原始错误。要找到它,您可以将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)));
容器寄存器(由(
()=>newmyservice(参数索引(0)),=>configurationA“,
重复使用。单身汉,
setup:setup.With(条件:r=>r.Parent.ImplementationType==typeof(MyAController));
集装箱登记册(由……制成)(
()=>newmyservice(参数索引(0)),=>configurationB“,
重复使用。单身汉,
setup:setup.With(条件:r=>r.Parent.ImplementationType==typeof(MyBController));
最重要的是,此设置不需要特殊的控制器注册


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

该错误是由于控制器设置不当造成的。DryIoc.WebApi扩展已经发现并注册了您的控制器,所以通常您不需要自己完成。稍后,我将为您提供特定设置的工作代码(来自问题注释)。但现在,“无参数构造函数…”背后的原因是:当DryIoc失败时,WebAPI会退回到使用
Activator.CreateInstance
作为控制器,这需要无参数构造函数。回退会掩盖原始错误。要找到它,您可以将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)));
容器寄存器(由(
()=>newmyservice(参数索引(0)),=>configurationA“,
重复使用。单身汉,
setup:setup.With(条件:r=>r.Parent.ImplementationType==typeof(MyAController));
集装箱登记册(由……制成)(
()=>newmyservice(参数索引(0)),=>configurationB“,
重复使用。单身汉,
setup:setup.With(条件:r=>r.Parent.ImplementationType==typeof(MyBController));
最重要的是,此设置不需要特殊的控制器注册


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

也许是个愚蠢的问题,但是您是否已将Web API配置为使用DryIoC?为什么控制器注册为Reuse.InResolutionScope而不是InWebRequest?当直接解析它们时,它会有效地使它们暂时化。是的,WebAPI配置了container.WithWebApi(GlobalConfiguration.Configuration);我在WebRequest和ResolutionScope中都尝试过。。。。如果控制器被发现并作为批注册(通过DryIoc.WebApi),则无法指定单个注册。但您可以将控制权放回IMyService,以决定在何处注入自身:
c.Register(由(()=>newmyservice(Arg.Index(0)),configA制成),Reuse.Singleton,setup:setup.With(condition:r=>r.ImplementationType==typeof(MyAController))
MyBController的类似功能。在这里,您可以避免使用服务密钥,而且无需注册配置。在ResolutionScope中,无论如何都不会工作。迪。WebApi在WebRequest中注册控制器。InWebRequest实际上是InirentNamedScope(重用.WebRequestScopeName)的糖。您可以使用(var scope=container.OpenScope(Reuse.WebRequestName){scope.Resolve controllers here}测试
中的控制器分辨率
也许是个愚蠢的问题,但您是否已将Web API配置为使用DryIoC?为什么控制器注册为Reuse.InResolutionScope而不是InWebRequest?当直接解析它们时,它会有效地使它们变为瞬态。是的,WebAPI配置为container.WithWebApi(GlobalConfiguration.Configuration);我在WebRequest和ResolutionScope中尝试了这两种方法,但都没有成功。鉴于控制器被发现并作为一个批注册(通过DryIoc.WebApi),您无法指定单独的注册。但您可以将控制权放回IMyService,以决定在何处注入自身:
c.Register(由(()=>new MyService(Arg.Index(0)),configA制作),Reuse.Singleton,setup:setup.With(条件:r=>r.ImplementationType==typeof(MyAController)))
MyBController也有类似的功能。在这里,您可以避免使用服务密钥,而且不需要注册配置。InResolutionScope无论如何都不会工作。DI.WebApi在WebRequest中注册控制器。InWebRequest实际上是InirentNamedScope(重用.WebRequestScopeName)的糖分。您可以使用(var scope=container.OpenScope(Reuse.WebRequestName){scope.Resolve controllers here}测试
中的控制器分辨率
不知道该设置。使用Condition,确实是一种很好的处理方法。使用Condition,确实是一种很好的处理方法。