简体   繁体   English

Autofac装饰使用装配扫描注册的开放式仿制药

[英]Autofac decorating open generics registered using assembly scanning

I'm trying to apply autofac decorator support feature to my scenario with no success. 我正在尝试将autofac装饰器支持功能应用到我的场景中,但没有成功。 It looks like in my case it doesn't assign the name to the registrations properly. 看起来在我的情况下,它没有正确地为注册分配名称。

Is there a way to register scanned assembly types with a name, so that I can later use it in the open generic decorator key? 有没有办法用名称注册扫描的程序集类型,以便我以后可以在开放的通用装饰器键中使用它?

Or maybe I'm completely wrong and doing something inappropriate here? 或者也许我完全错了,在这里做一些不合适的事情?

builder.RegisterAssemblyTypes(typeof(IAggregateRepositoryAssembly).Assembly)
    .AsClosedTypesOf(typeof(IAggregateViewRepository<>)) //here I need name, probably
    .Named("view-implementor", typeof(IAggregateViewRepository<>))
    .SingleInstance();

builder.RegisterGenericDecorator(typeof(CachedAggregateViewRepository<>),
    typeof(IAggregateViewRepository<>), fromKey: "view-implementor");

Here's an attempt, not in front of Visual Studio so overload resolution might not be exactly right: 这是一次尝试,而不是在Visual Studio之前,因此重载决策可能不完全正确:

builder.RegisterAssemblyTypes(typeof(IAggregateRepositoryAssembly).Assembly)
    .As(t => t.GetInterfaces()
              .Where(i => i.IsClosedTypeOf(typeof(IAggregateViewRepository<>))
              .Select(i => new KeyedService("view-implementor", i))
              .Cast<Service>())
    .SingleInstance();
  • Named() is just syntactic sugar for Keyed() , which associates the component with a KeyedService Named()只是KeyedService Keyed()语法糖,它将组件与KeyedService相关联
  • As() accepts a Func<Type, IEnumerable<Service>> As()接受Func<Type, IEnumerable<Service>>

You will also need: 您还需要:

using Autofac;
using Autofac.Core;

If you wanted to clean up your registration code you could also define the following additional extension method (very verbose and based on the autofac source for the other overload, but it only needs to be defined once): 如果您想清理注册码,您还可以定义以下附加扩展方法(非常详细,基于其他重载的autofac源,但只需要定义一次):

using Autofac;
using Autofac.Builder;
using Autofac.Core;
using Autofac.Features.Scanning;

public static class AutoFacExtensions
{
    public static IRegistrationBuilder<TLimit, TScanningActivatorData, TRegistrationStyle>
        AsClosedTypesOf<TLimit, TScanningActivatorData, TRegistrationStyle>(
            this IRegistrationBuilder<TLimit, TScanningActivatorData, TRegistrationStyle> registration,
            Type openGenericServiceType,
            object key)
        where TScanningActivatorData : ScanningActivatorData
    {
        if (openGenericServiceType == null) throw new ArgumentNullException("openGenericServiceType");

        return registration.As(t => 
            new[] { t }
            .Concat(t.GetInterfaces())
            .Where(i => i.IsClosedTypeOf(openGenericServiceType))
            .Select(i => new KeyedService(key, i)));
    }
} 

That would allow you to simply do this: 那将允许你简单地这样做:

builder.RegisterAssemblyTypes(typeof(IAggregateRepositoryAssembly).Assembly)
    .AsClosedTypesOf(typeof(IAggregateViewRepository<>), "view-implementor")
    .SingleInstance();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM