如何用Autofac装饰一种特定类型?

时间:2019-03-14 10:38:14

标签: c# dependency-injection decorator autofac

使用CQS模式,我有这样的查询:

[GETID3_VERSION] => 1.9.4-20120530
[error] => Array
    (
        [0] => Could not open "

当然,我有很多查询及其所属的QueryHandlers。现在,我遇到一种情况,我只想装饰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; } } 。我不想装饰其余的查询。

我正在使用Autofac,但无法正常工作。

这是查询的注册方式:

MyQueryHandler

这是我要用于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

那么如何使用Autofac将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的专用装饰器?

1 个答案:

答案 0 :(得分:1)

我终于按照自己想要的方式工作了。这是我的解决方案:

让装饰器打开,而不是关闭类型:

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以来的新功能,这解决了我的问题。