Autofac装饰用组装扫描

时间:2016-10-27 05:51:28

标签: c# decorator autofac

我正在尝试使用Autofac构建一个查询管道,但似乎无法弄清楚如何正确地装饰它。工作流程

从缓存中检索>从DB中检索>存储在缓存中>变换

以下是当前配置

builder.RegisterAssemblyTypes(assemblies)
    .Where(x => x.Name.EndsWith("Transform"))
    .As(o => o.GetInterfaces()
        .Where(i => i.IsClosedTypeOf(typeof(IQuery<,>)))
        .Select(i => new KeyedService("Transform", i))
    );

builder.RegisterGenericDecorator(
    typeof(SaveToCache<,>),
    typeof(IQuery<,>),
    fromKey: "Transform",
    toKey: "SaveCache"
);

builder.RegisterDecorator<IQuery<GetPerson, PersonDto>>(
    (x, decorator) => new GetPersonQuery(decorator),
    fromKey: "SaveCache",
    toKey: "QueryDb"
);

builder.RegisterGenericDecorator(
    typeof(RetrieveFromCache<,>),
    typeof(IQuery<,>),
    fromKey: "QueryDb"
);

因此链条有效,但下面的注册并不理想,因为新查询需要手动注册

builder.RegisterDecorator<IQuery<GetPerson, PersonDto>>(
    (x, decorator) => new GetPersonQuery(decorator),
    fromKey: "SaveCache",
    toKey: "QueryDb"
);

那么无论如何使用某种形式的扫描机制来注册装饰器?

我想你可以扫描程序集并找到具体的实现然后注册它,但它仍然不那么直接:(

var type = typeof(IQuery<,>);

var queries = assemblies
    .SelectMany(x => x.GetTypes())
    .Where(y => y.GetInterfaces().Any(z => z.IsGenericType && z.GetGenericTypeDefinition() == type) && y.Name.EndsWith("Query"));

foreach (var query in queries)
{
    // ?
}

0 个答案:

没有答案