سؤال

I'm trying to apply autofac decorator support feature to my scenario with no success. 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:

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
  • As() accepts a 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):

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 مع الإسناد
لا تنتمي إلى StackOverflow
scroll top