这个概念很受欢迎,但我还没有找到答案。
我有以下类结构
public interface IMessage
{
}
public class MessageA : IMessage
{
}
public class MessageB : IMessage
{
}
public interface IMessageHandler<T> where T : IMessage
{
void Handle(TMessage message);
}
public interface MessageAHandler : IMessageHandler<MessageA>
{
}
public interface MessageBHandler : IMessageHandler<MessageB>
{
}
public class MessageProcessor
{
public void Process(IMessage)
{
if (IMessage is MessageA)
{
// handler for messageA has to be invoked
}
else if (IMessage is MessageB)
{
// handler for messageB has to be invoked
}
}
}
现在我正在使用Ninject并将我的绑定添加到
中Bind<IMessageHandler<MessageA>>.To<MessageAHandler>();
Bind<IMessageHandler<MessageB>>.To<MessageBHandler>();
我想在绑定模块中以某种方式执行所有绑定魔法以选择处理程序。 MessageProcessor类应该只传递某些,它调用它来处理消息。
是什么是什么以及如何在绑定模块中完成它是我无法弄清楚的。有人可以帮忙!
由于
答案 0 :(得分:2)
使用ninject约定扩展https://github.com/ninject/ninject.extensions.conventions,选择继承自typeof(IMessageHandler<>)
的所有类型,然后使用自定义IBindingGenerator
实现。例如:
this.Kernel.Bind(x => x
.FromThisAssembly()
.IncludingNonePublicTypes()
.SelectAllClasses()
.InheritedFrom(typeof(IMessageHandler<>))
.BindWith<MessageHandlerBindingGenerator>());
在Binding Builder中使用反射来创建特定的接口类型IMessageHandler<XYZ>
并像这样使用它.Kernel.Bind(interfaceType).To(type)。
如果您愿意,我可以提供完整的实施。
好的,我尽量保持简单,如果你真的需要更复杂的东西,那么请告诉我:
public interface IMessage { }
public class MessageA : IMessage { }
public class MessageB : IMessage { }
public interface IMessageHandler<T>
where T : IMessage
{
void Handle(T message);
}
public class MessageHandlerA : IMessageHandler<MessageA>
{
public void Handle(MessageA message)
{
Console.WriteLine("Message A handled");
}
}
public class MessageHandlerB : IMessageHandler<MessageB>
{
public void Handle(MessageB message)
{
Console.WriteLine("Message B handled");
}
}
public class MessageProcessor
{
private static readonly MethodInfo GenericProcessMethod = typeof(MessageProcessor).GetMethod("ProcessGeneric");
private readonly IResolutionRoot resolutionRoot;
public MessageProcessor(IResolutionRoot resolutionRoot)
{
this.resolutionRoot = resolutionRoot;
}
public void Process(IMessage message)
{
GenericProcessMethod.MakeGenericMethod(message.GetType())
.Invoke(this, new object[] { message });
}
public void ProcessGeneric<TMessage>(TMessage message)
where TMessage : IMessage
{
var handler = this.resolutionRoot.Get<IMessageHandler<TMessage>>();
handler.Handle(message);
}
}
public class Test
{
private readonly IKernel kernel;
public Test()
{
this.kernel = new StandardKernel();
this.kernel.Bind(x => x
.FromThisAssembly()
.IncludingNonePublicTypes()
.SelectAllClasses()
.InheritedFrom(typeof(IMessageHandler<>))
.BindSingleInterface());
}
[Fact]
public void IntegrationTest()
{
var messageProcessor = this.kernel.Get<MessageProcessor>();
messageProcessor.Process(new MessageA());
messageProcessor.Process(new MessageB());
}
}
([Fact]属性来自xUnit,我用它来运行测试。)
我遗漏了interface IMessageAHandler : IMessageHandler<MessageA>
等接口,你真的需要它们吗?他们让事情变得更复杂。对于绑定生成器或者它更复杂以确定消息处理器需要使用的类型。