Как насчет этого (показаны только измененные детали):
Publish
Ключевым моментом здесь является сделать T
метод универсальным, что означает, что вы получаете ссылку T
на тип для типа команды, которую затем можно использовать для выполнения приведения. Ограничения параметров типа просто гарантируют, что только an 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);
}
}
Это побочный вопрос к вашему первоначальному вопросу, но он может показаться разумным для интерфейса МОК.