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