Как сделать открытую универсальную цепочку декораторов с Unity + UnityAutoRegistration
Ушел сегодня по интересной касательной после прочтенияэта статья об оформлении командного обработчика, Я хотел посмотреть, смогу ли я реализовать шаблон, используя Unity вместоSimpleInjectorи до сих пор это оказывается чрезвычайно сложно.
Первое, что мне нужно было сделать, это установитьUnityAutoRegistration разрешить открытый дженерикICommandHandler<TCommand>
интерфейс. Текущее решение для этого аспекта заключается в следующем:
Container = new UnityContainer().LoadConfiguration();
Container.ConfigureAutoRegistration()
.ExcludeSystemAssemblies()
.Include(type => type.ImplementsOpenGeneric(typeof(ICommandHandler<>)),
(t, c) => c.RegisterType(typeof(ICommandHandler<>), t)
)
.ApplyAutoRegistration()
;
Это работает для первой части, решая любыеОдин ICommandHandler<TCommand>
, До сих пор разочаровывает реализация обработчика украшений. Как только я добавлю второйICommandHandler<TCommand>
в качестве декоратора Unity создает исключение StackOverflowException. Я не знаю достаточно о внутренностях Unity, но я предполагаю, что это потому, что он не может определить, какой экземпляр разрешить - обработчик команд или декоратор обработчиков команд - поскольку оба реализуютICommandHandler<TCommand>
интерфейс.
Погуглил повёл менясначала к этой статье, который объясняет, как это сделать в том, что я считаю методом грубой силы. Я также нашелэти Связанный страницы но ни одно не является полным решением моей проблемы (и я слишком невежественен, чтобы понять это для себя).
Потом я нашелэта статья, которая, кажется, касается моих же проблем, Однако решение Бифи не учитывает открытые дженерики. В настоящее время большинство наших зависимостей загружаются из раздела единицы в файле .config, поэтому я не хочу писать тонну скомпилированного кода для каждого обработчика или декоратора. Кажется, что наличие некоторого UnityContainerExtension и DecoratorBuildStrategy - верный путь, но я не могу понять это. Я немного поигрался с кодом Бифи и совершенно застрял. Мои попытки изменить его код для учета непатентованных средств привели к появлению BadImageFormatExceptions (была предпринята попытка загрузить программу с неверным форматом. (Исключение из HRESULT: 0x8007000B)).
Мне нравится идея сделать это для реализации цепочки декоратора, потому что она короткая, и есть только 1 строка для каждой проблемы:
var container = new Container();
// Go look in all assemblies and register all implementations
// of ICommandHandler<T> by their closed interface:
container.RegisterManyForOpenGeneric(typeof(ICommandHandler<>),
AppDomain.CurrentDomain.GetAssemblies());
// Decorate each returned ICommandHandler<T> object with an
// TransactionCommandHandlerDecorator<T>.
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(TransactionCommandHandlerDecorator<>));
// Decorate each returned ICommandHandler<T> object with an
// DeadlockRetryCommandHandlerDecorator<T>.
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(DeadlockRetryCommandHandlerDecorator<>));
... но я не хочу менять свой контейнер с Unity на Simple Injector, если мне не нужно.
Так что мой вопрос заключается в том, как я могу реализовать открытую универсальную цепочку декоратора с использованием Unity (плюсUnityAutoRegistration
)?