Хитрость заключается в том, чтобы сделать общий интерфейс:
public interface IMessageHandler<T>
{
void Handle(T message);
}
public class MonkeyHandler : IMessageHandler<Monkey>
{
public void Handle(Monkey message) {}
}
Чтобы решить обработчик просто сделать:
var monkeyHandler = yourContainer.Resolve<IMessageHandler<Monkey>>();
Проблемы в том, что если вы получаете сообщения как object
вы не можете сделать переход от объекта к воспроизведенным во время компиляции.
object message = endPoint.Recieve();
//not fun to do this:
if (message is Monkey)
container.Resolve<IMessageHandler<Monkey>>((Monkey)message);
Вместо этого вам необходимо выполнить переход с объектов на типизированные обработчики.
public interface IMessageHandler
{
void Handle(object message);
}
public interface IMessageHandler<T> : IMessageHandler
{
void Handle(T message);
}
public class MonkeyHandler : IMessageHandler<Monkey>
{
public void Handle(Monkey message) {}
//hide from the public API
void IMessageHandler.Handle(object message)
{
Handle((Monkey)message);
}
}
.. а это значит, что теперь вы можете найти его с помощью Type
:
var genericInterfaceType = typeof(IMessageHandler<>).MakeGenericType(message.GetType());
var handlerObj = container.Resolve(genericInterfaceType);
.. так что вы можете бросить его в базовый интерфейс и вызывать его:
var handler = (IMessageHandler)handlerObj;
handler.Handle(message);
yay. У нас ЦЕЛЬ!
Чтобы удалить повторяющиеся задачи по переходу от объектов, набранный в обработчиках можно создать базовый класс:
public abstract class HandlerBase<T> : IMessageHandler<T>
{
public abstract void Handle(Monkey message);
void IMessageHandler.Handle(object message)
{
Handle((T)message);
}
}
public class MonkeyHandler : HandlerBase<Monkey>
{
public override void Handle(Monkey message)
{
}
}
Вам нужен интерфейс обработчика, может быть один общий и РЕГИСТР обработчики для соответствующих типов обработчиков , Затем, исходя из типа сообщения, вам нужно спросить контейнер для зарегистрированного типа обработчика, который соответствует типу сообщения (таким образом, общий тип обработчика делает его намного проще). Но я с @stuartd, контейнер слишком важен для такой ответственности, подходящая фабрика обработчиков будет лучше здесь. –
Обработчики сообщений разворачиваются в разных местах и постоянно добавляются, я не хочу использовать словарь, потому что, чем каждый новый обработчик, который я добавляю, мне нужно будет перейти в словарь и добавить их, и они уже зарегистрированы в контейнер МОК. поэтому кажется избыточным –
Какой механизм вы используете для динамической регистрации новых обработчиков с помощью контейнера IOC? Я думаю, вы должны быть в состоянии связать это, но трудно сказать, не зная подробности. – StriplingWarrior