Mas*_*oud 13 c# structuremap dependency-injection multiple-instances
我的项目中有一个接口,有2个类实现它:
public interface IService
{
int DoWork();
}
public class Service1:IService
{
public int DoWork()
{
return 1;
}
}
public class Service2:IService
{
public int DoWork()
{
return 2;
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个依赖于它的命令处理程序IService:
public CommandHandler1:ICommandHandler<CommandParameter1>
{
IService _service;
public CommandHandler1(IService service)
{
_service = service
}
public void Handle()
{
//do something
_service.DoWork();
//do something else
}
}
public interface ICommandHandler<TCommandParameter>
where TCommandParameter :ICommandParameter
{
void Handle(TCommandParameter parameter);
}
public interface ICommandParameter
{
}
Run Code Online (Sandbox Code Playgroud)
我想基于用户选择注入Service1或Service2我CommandHandler1.假设我有一个enum用户可以从中选择一个值:
public enum Services
{
Service_One,
Service_Two
}
Run Code Online (Sandbox Code Playgroud)
如果用户选择Service_One我想注入Service1我的命令处理程序,如果他选择Service_Two我想注入Service2命令处理程序.
我知道我可以使用命名实例,然后调用ObjectFactory.GetInstance<IService>().Named("Service1")例如,但有没有办法实现这个StructureMap并阻止使用Service Locator模式?
使用运行时条件阻止构建对象图.应该修复对象图.使用运行时决策来确定通过对象图的路径.
你似乎在这里缺少的是一个抽象,它允许将请求委托给正确的IService实现; 我们称之为IServiceDispatcher:
interface IServiceDispatcher {
int DoWork(Services data);
}
sealed class ServiceDispatcher : IServiceDispatcher {
private readonly IService service1;
private readonly IService service2;
// NOTE: Feel free to inject the container here instead, as long as
// this class is part of your composition root.
public ServiceDispatcher(IService service1, IService service2) {
this.service1 = service1;
this.service2 = service2;
}
public int DoWork(Services data) {
return this.GetService(data).DoWork();
}
private IService GetService(Services data) {
switch (data) {
case Services.Service_One: return this.service1;
case Services.Service_Two: return this.service2;
default: throw new InvalidEnumArgumentException();
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在您CommandHandler1可以依靠IServiceDispatcher:
public CommandHandler1 : ICommandHandler<CommandParameter1> {
private readonly IServiceDispatcher serviceDispatcher;
public CommandHandler1(IServiceDispatcher serviceDispatcher) {
this.serviceDispatcher = serviceDispatcher;
}
public void Handle(CommandParameter1 commandParameter) {
//do something
this.serviceDispatcher.DoWork(commandParameter.Service);
//do something else
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,这IServiceDispatcher是一个非常难看的名称,从技术上描述了正在发生的事情.这是一个坏主意,因为界面应该在功能上描述你想要的东西.但是,由于您没有为您的问题提供任何特定于域的上下文,这是我能提出的最佳名称;-)
| 归档时间: |
|
| 查看次数: |
1634 次 |
| 最近记录: |