Замок Виндзор: лучший способ реализовать 2 уровня (вложенных) фабрик?
У нас есть шаблон, который мы использовали несколько раз, в соответствии с которым мы реализуем обработчики и фабрики в отдельных библиотеках. Мы настраиваем exe во время выполнения, сообщая, какие DLL загружены, и, следовательно, какие обработчики доступны для приложения.
Мы делаем это потому, что у нас есть настраиваемая обработка для некоторых клиентов, а также она обеспечивает большую гибкость, поскольку мы можем быстро разрабатывать новые обработчики изолированно, а также тестировать и развертывать их с уверенностью, что мы даже не затронули другие части работающего приложения. Мы также можем исправлять обработчики, просто вставив одну заменяющую DLL, у нас есть клиенты со строгими процедурами управления изменениями, и они обожают это.
Для этого шаблон опирается на два уровня фабрик, конкретные фабрики, которые реализуют определенные обработчики, и всеобъемлющую фабрику (которую мы называемпоставщик). Поставщик выбирает, какую фабрику обработчиков использовать для создания обработчика.
Вопрос: есть ли в Виндзоре что-то, что упростит этот процесс для нас?
В частности, я ищу что-то, что может опустить объекты фабрики Handler, эточувствует как то, что должно быть в состоянии сделать.
Я прочитал оТипизированный завод иUsingFactory
& UsingFactoryMethod
методы, но я не понимаю, как они могли бы помочь здесь.
Тем не менее, я часто нахожу документацию Castle Windsor тупой, поэтому я могу упустить что-то очевидное Или же Есть ли просто лучший способ получить ту же конечную цель, которую я не рассматривал.
Вот некоторый код для иллюстрации, первое сообщение, обработчик и фабричные интерфейсы
public interface IMessage
{
string MessageType { get; }
}
public interface IMessageHandler
{
void Process(IMessage message);
}
public interface IMessageHandlerFactory
{
bool CanProcessType(string type);
IMessageHandler Create();
}
Во второй DLL мы реализуем обработчик и фабрику для Type1
public class Type1MessageHandler
: IMessageHandler
{
public void Process(IMessage message) { }
}
public class Type1MessageHandlerFactory
: IMessageHandlerFactory
{
public bool CanProcessType(string type)
{
return type == "Type1";
}
public IMessageHandler Create()
{
return new Type1MessageHandler();
}
}
В третьем Dll мы реализуем обработчик и фабрику для Type2
public class Type2MessageHandler
: IMessageHandler
{
public void Process(IMessage message) { }
}
public class Type2MessageHandlerFactory
: IMessageHandlerFactory
{
public bool CanProcessType(string type)
{
return type == "Type2";
}
public IMessageHandler Create()
{
return new Type2MessageHandler();
}
}
В сервисе windows мы реализуем провайдера
public interface IMessageHandlerProvider
{
IMessageHandler Create(string messageType);
}
public class MessageHandlerProvider
: IMessageHandlerProvider
{
IEnumerable<IMessageHandlerFactory> factories;
public MessageHandlerProvider(IWindsorContainer wc)
{
factories = wc.ResolveAll<IMessageHandlerFactory>();
}
public IMessageHandler Create(string messageType)
{
foreach (var factory in factories)
if (factory.CanProcessType(messageType))
return factory.Create();
throw new UnableToFindMessageHandlerFactoryForType(messageType);
}
}
Сервис, который действительно нуждается в обработчиках, использует только провайдера
public class MessageService
{
public MessageService(IMessageHandlerProvider handlerProvider) {}
}