Как насчет этого (показаны только измененные детали): -
// Handler interface
interface IHandles<T> where T : ICommand {
void Handle(T command);
}
// Bus interface
interface IBus {
void Publish<T>(T cmd) where T : ICommand;
}
// Bus implementation
class BusImpl : IBus {
public void Publish<T>(T cmd) where T : ICommand {
var handler = (IHandles<T>)IoC.Resolve(typeof(IHandles<T>));
handler.Handle(cmd);
}
}
Ключ здесь заключается в том, чтобы сделать метод Publish
универсальным, что означает, что вы получаете ссылку на тип T
натип команды, которую затем можно использовать для приведения.Ограничения параметра типа просто гарантируют, что только ICommand
может быть передано, как и раньше.
КСТАТИ - Я проверил это, и это работает, вот полный код: -
public static void Main(){
new BusImpl().Publish(new HelloCommand());
}
// IoC wrapper
static class IoC {
public static object Resolve(Type t) {
return new ConcreteHandlerImpl();
}
}
// Handler interface
interface IHandles<T> where T : ICommand {
void Handle(T command);
}
// Command interface
interface ICommand {
}
// Handler implementation
class ConcreteHandlerImpl : IHandles<HelloCommand> {
public void Handle(HelloCommand cmd) {
Console.WriteLine("Hello Command executed");
}
}
public class HelloCommand:ICommand{}
// Bus interface
interface IBus {
void Publish<T>(T cmd) where T : ICommand;
}
// Bus implementation
class BusImpl : IBus {
public void Publish<T>(T cmd) where T : ICommand {
var handler = (IHandles<T>)IoC.Resolve(typeof(IHandles<T>));
handler.Handle(cmd);
}
}
- ОБНОВЛЕНИЕ -
Как указал Питер Лиллевольд, вам также следует подумать о добавлении параметра типа в метод контейнера IOC следующим образом: -
// IoC wrapper
static class IoC {
public static T Resolve<T>() {
...
}
}
это упростит вашувызывающая сторона выглядит так: -
// Bus implementation
class BusImpl : IBus {
public void Publish<T>(T cmd) where T : ICommand {
var handler = IoC.Resolve<IHandles<T>>();
handler.Handle(cmd);
}
}
Это побочный вопрос к вашему первоначальному вопросу, но может показаться разумным для интерфейса IOC.