Как украсить один конкретный тип с помощью Autofac? - PullRequest
1 голос
/ 14 марта 2019

Используя шаблон CQS, у меня есть такой запрос:

public class MyQuery : IQuery<View<SingleView>>
{
    public string Token { get; set; }

    public Criteria Criteria { get; set; }
}

public class MyQueryHandler : IQueryHandler<MyQuery, View<SingleView>>
{
    private readonly IProductRepository _productRepository;

    public MyQueryHandler(IProductRepository productRepository)
    {
        _productRepository = productRepository;
    }

    public View<SingleView> Handle(MyQuery query)
    {
        var data = // get my data

        return data;
    }
}

Конечно, у меня много запросов и принадлежащих им QueryHandlers.Теперь у меня есть ситуация, которую я хочу украсить только MyQueryHandler.Я не хочу украшать остальные запросы.

Я использую Autofac, но просто не могу заставить его работать.

Вот как регистрируются запросы:

builder.RegisterAssemblyTypes(assemblies)
    .As(type => type.GetInterfaces()
        .Where(interfaceType => interfaceType.IsClosedTypeOf(typeof(IQueryHandler<,>)))
        .Select(interfaceType => new KeyedService("queryHandler", interfaceType)));

// Register query decorators
builder.RegisterGenericDecorator(
    typeof(LogQueryDecorator<,>),
    typeof(IQueryHandler<,>),
    "queryHandler");

А вот декоратор, который я хочу использовать для MyQueryHandler:

public class SaveMyQueryData : IQueryHandler<MyQuery, View<SingleView>>
{
    private readonly IQueryHandler<MyQuery, View<SingleView>> _queryHandler;
    private readonly IProductRepository _productRepository;

    public SaveMyQueryData(
        IQueryHandler<MyQuery, View<SingleView>> queryHandler,
        IProductRepository productRepository)
    {
        _queryHandler = queryHandler;
        _productRepository = productRepository;
    }

    public View<SingleView> Handle(MyQuery query)
    {
        var result = _queryHandler.Handle(query);

        // do something with result

        return result;
    }
}

Так как я могузарегистрировать SaveMyQueryData в качестве декоратора только для MyQueryHandler, используя Autofac?

1 Ответ

1 голос
/ 14 марта 2019

У меня наконец-то получилось так, как я хочу. Вот мое решение:

Сделать декоратор открытым вместо закрытого типа:

public class SaveMyQueryData : IQueryHandler<Q, R>
{
    private readonly IQueryHandler<Q, R> _queryHandler;
    private readonly IProductRepository _productRepository;

    public SaveMyQueryData(
        IQueryHandler<Q, R> queryHandler,
        IProductRepository productRepository)
    {
        _queryHandler = queryHandler;
        _productRepository = productRepository;
    }

    public Q Handle(Q query)
    {
        var result = _queryHandler.Handle(query);
        var view = result as View<SingleView>; 

        // do something with view

        return result;
    }
}

Затем при регистрации типа с помощью Autofac сделайте следующее:

builder.RegisterGenericDecorator(
  typeof(SaveMyQueryData<,>), 
  typeof(IQueryHandler<,>), 
  context => context.ImplementationType == typeof(MyQueryHandler));

Последняя строка содержит магию. С третьим параметром RegisterGenericDecorator вы можете указать условие, когда применять декоратор. Это новое с версии Autofac 4.9, и это решило мою проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...