Autofa c - зарегистрировать GenericDecorators для модульных тестов - PullRequest
0 голосов
/ 25 мая 2020

Я использую Autofa c версию 5.2.0 и у меня несколько Decorators (https://autofaccn.readthedocs.io/en/latest/advanced/adapters-decorators.html)

Я регистрирую их так:

containerBuilder.RegisterGenericDecorator(
    typeof(QueryHandlerExceptionDecorator<,>),
    typeof(IQueryHandler<,>));

Это прекрасно работает.

Сама регистрация происходит динамически, в зависимости от файла конфигурации или оператора Action<ContainerBuilder>.

В своих модульных тестах я хотел бы сделать что-то вроде этого:

Assert.IsTrue(containberBuilder.IsGenericDecoratorRegistered(
    typeof(QueryHandlerExceptionDecorator<,>)));

Но ни класс ContainerBuilder, ни реализация IContainer после вызова containerBuilder.Build(); не предлагают никаких методов или свойство для получения регистраций декораторов.

Я наткнулся на следующую статью с настраиваемым источником регистрации: { ссылка }, но даже там я не смог найти способ получить список зарегистрированных декораторов .

Я мог бы, конечно, модульно протестировать некоторые функции, которые предлагает декоратор Speci c, когда я получаю декорированный экземпляр и предполагаю, что он зарегистрирован этим, но я не хочу этого делать.

Ответы [ 2 ]

0 голосов
/ 27 мая 2020

Вы можете получить доступ к декораторам для данной службы, используя метод IComponentRegistry.DecoratorsFor, доступный из свойства ComponentRegistry построенного контейнера.

Вы можете передать этому методу экземпляр TypedService, чтобы получить регистрации декораторов, например:

var decorators = container.ComponentRegistry.DecoratorsFor(new TypedService(typeof(IDecoratedService)));
0 голосов
/ 27 мая 2020

Поскольку я не мог придумать правильного решения, чтобы узнать, какие декораторы настроены напрямую, я пришел к решению моего "регистратора":

public interface IDecoratorRegistrar
{
    void RegisterGenericDecorator(ContainerBuilder builder, Type decoratorType, Type serviceType);
    void RegisterGenericDecorator(ContainerBuilder builder, Type decoratorType, Type serviceType);
    void RegisterDecorator(ContainerBuilder builder, Type decoratorType, Type serviceType);
    void RegisterDecorator(ContainerBuilder builder, Type decoratorType, Type serviceType, Func<IDecoratorContext, bool>? condition);
}

Это фактическая реализация для Autofa c регистрации:

public class DecoratorRegistrar : IDecoratorRegistrar
{
    public void RegisterGenericDecorator(ContainerBuilder builder, Type decoratorType, Type serviceType)
    {
        RegisterGenericDecorator(builder, decoratorType, serviceType, null);
    }
    public void RegisterGenericDecorator(ContainerBuilder builder, Type decoratorType, Type serviceType, Func<IDecoratorContext, bool>? condition)
    {
        builder.RegisterGenericDecorator(decoratorType, serviceType, condition);
    }
    public void RegisterDecorator(ContainerBuilder builder, Type decoratorType, Type serviceType)
    {
        RegisterDecorator(builder, decoratorType, serviceType, null);
    }
    public void RegisterDecorator(ContainerBuilder builder, Type decoratorType, Type serviceType, Func<IDecoratorContext, bool>? condition)
    {
        builder.RegisterDecorator(decoratorType, serviceType, condition);
    }
}

Реализация модульных тестов:

public class MockDecoratorRegistrar : IDecoratorRegistrar
{
    public IList<(Type decoratorType, Type serviceType)> Decorators { get; } = new List<(Type decoratorType, Type serviceType)>();
    public IList<(Type decoratorType, Type serviceType)> GenericDecorators { get; } = new List<(Type decoratorType, Type serviceType)>();

    public void RegisterDecorator(ContainerBuilder builder, Type decoratorType, Type serviceType)
    {
        Decorators.Add((decoratorType, serviceType));
    }

    public void RegisterDecorator(ContainerBuilder builder, Type decoratorType, Type serviceType, Func<IDecoratorContext, bool>? condition)
    {
        Decorators.Add((decoratorType, serviceType));
    }

    public void RegisterGenericDecorator(ContainerBuilder builder, Type decoratorType, Type serviceType)
    {
        GenericDecorators.Add((decoratorType, serviceType));
    }

    public void RegisterGenericDecorator(ContainerBuilder builder, Type decoratorType, Type serviceType, Func<IDecoratorContext, bool>? condition)
    {
        GenericDecorators.Add((decoratorType, serviceType));
    }
}

Чтобы зарегистрировать декоратор, я сейчас вызываю:

decoratorRegistrar.RegisterGenericDecorator(containerBuilder, typeof(ActionCommandHandlerExceptionDecorator<>), typeof(IActionCommandHandler<>));

decoratorRegistrar является экземпляром DecoratorRegistrar или MockDecoratorRegistrar в модульных тестах.

В моих модульных тестах я теперь могу легко проверить регистрации, позвонив:

mockDecoratorRegistrar.GenericDecorators.Should().Contain(item => item.decoratorType == expectedType);

Эта абстракция решает мои фактические вопрос. Тем не менее: если у кого-то есть решение для доступа к регистрации Decorator непосредственно из Autofa c, сообщите мне.

...