将具有不同配置的服务注入控制器
Inject service with different configuration into controller
在 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.
所以我想,我需要以不同的方式注册控制器...但是如何?
任何帮助将不胜感激....
该错误是由于控制器设置不当造成的。 DryIoc.WebApi 扩展已经发现并注册了你的控制器,所以通常你不需要自己做。稍后我将为您提供特定设置的工作代码(来自问题评论)。但现在 "parameterless constructor.." 背后的原因是:当 DryIoc 失败时,WebAPI 回退到对控制器使用 Activator.CreateInstance
,它需要无参数构造函数。回退掩盖了原始的 DryIoc 错误。要找到它,您可以将 DryIoc.WebApi 扩展设置为:
container = container.WithWebApi(throwIfUnresolved: type => type.IsController());
您案例的工作设置,它将条件依赖项注册到 select 注入控制器:
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)));
主要是这个设置不需要特殊的控制器注册。
此外,您可以避免使用服务密钥,也无需单独注册配置字符串。
在 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.
所以我想,我需要以不同的方式注册控制器...但是如何?
任何帮助将不胜感激....
该错误是由于控制器设置不当造成的。 DryIoc.WebApi 扩展已经发现并注册了你的控制器,所以通常你不需要自己做。稍后我将为您提供特定设置的工作代码(来自问题评论)。但现在 "parameterless constructor.." 背后的原因是:当 DryIoc 失败时,WebAPI 回退到对控制器使用 Activator.CreateInstance
,它需要无参数构造函数。回退掩盖了原始的 DryIoc 错误。要找到它,您可以将 DryIoc.WebApi 扩展设置为:
container = container.WithWebApi(throwIfUnresolved: type => type.IsController());
您案例的工作设置,它将条件依赖项注册到 select 注入控制器:
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)));
主要是这个设置不需要特殊的控制器注册。
此外,您可以避免使用服务密钥,也无需单独注册配置字符串。