AutoFac - регистрация декоратора для некоторых открытых Generic

Я пытаюсь установить модуль Autofac, который кажется сложным требованием.

вот оно:

У меня есть общий интерфейс:

public interface IMyInterface

У меня есть куча классов, которые реализуют этот интерфейс

например

class MyImpl1 : IMyInterface { }
class MyImpl2 : IMyInterface { }
class MyImpl3 : IMyInterface { }

Наконец, у меня есть декоратор:

class MyDecorator : IMyInterface

Я только хочуУкрасьте» реализации (изMyInterface), которые имеют определенный атрибут. Таким образом, все реализации MyInterface, которые имеют атрибут[MyAttribute] украшены MyDecorator.I '

м близко, но сигары еще нет:

var builder = new ContainerBuilder();        

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
    .Where(type => type.GetCustomAttributes(true)
        .Any(attr => attr.GetType() == typeof(MyAttribute)))
    .AsClosedTypesOf(typeof (IMyInterface))
    .Keyed("CachableQueries", typeof(IMyInterface));

builder.RegisterGenericDecorator(typeof(MyDecorator),
    typeof(IMyInterface), "CachableQueries");

var container = builder.Build();

Console.WriteLine(container.Resolve());
Console.WriteLine(container.Resolve());

Я понимаю, что последний кусок головоломки - это ключ, на самом деле нужно передать тип вKeyed("CachableQueries", THE_TYPE); но это не игра в мяч.

Обновить

Немеш отправил меня в правильном направлении.

В качестве части моего вопроса я забыл упомянуть, что мне также необходимо зарегистрировать все реализации IMyInterface <,> это нене иметь [MyAttribute].

Я сделал это в два этапа. Сначала зарегистрируйте типы с помощью Decorator, а затем зарегистрируйте остальные.

Мое решение: я знаю, что это нуждается в рефакторинге, но в качестве доказательства концепции. оно работает.

class Program
{
    static void Main(string[] args)
    {
        var builder = new ContainerBuilder();

        //Get all the types we're interested in (that inherit IMyInterface)
        List typesToQuery = Assembly.GetExecutingAssembly().GetTypes()
            .Where(type => type.GetInterfaces()
                    .Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof (IMyInterface))).ToList();

        //Even tho the decorator inherits IMyInterface (we don't want to process it)
        typesToQuery.Remove(typeof (MyDecorator)); 


        //build a dictionary of all the types, so we don't process them again.
        Dictionary typesToProcess = typesToQuery.ToDictionary(queryType => queryType, queryType => false);


        //Register all types that have [MyAttribute]
        foreach (var type in typesToQuery
                    .Where(type => type.GetCustomAttributes(true)
                    .Any(attr => attr.GetType() == (typeof(MyAttribute)))))
        {
            builder.RegisterType(type).Keyed("CachableQueries",
                type.GetInterfaces()
                    .First(i =>
                            i.IsGenericType &&
                            i.GetGenericTypeDefinition() == typeof(IMyInterface)));

            typesToProcess[type] = true; //update, so this type isn't processed again
        }

        //Decorate the correct ones
        builder.RegisterGenericDecorator(typeof(MyDecorator), typeof(IMyInterface), fromKey: "CachableQueries");

        //Register the rest of the types we're interested 
        foreach (Type type in typesToProcess.Where(kvp => kvp.Value == false).Select(pair => pair.Key))
        {
            builder.RegisterType(type).As(
                type.GetInterfaces()
                    .First(i =>
                            i.IsGenericType &&
                            i.GetGenericTypeDefinition() == typeof(IMyInterface)));

        } 

        var container = builder.Build();

        Console.WriteLine(container.Resolve());
        Console.WriteLine(container.Resolve());

        //Result:
        //AutoFacPlay.MyDecorator`2[System.String,System.Boolean]  - this one was decorated (as it has MyAttribute)
        //AutoFacPlay.MyImplementation2 - this one wasn't decorated

        Console.ReadLine();

    }
}

Ответы на вопрос(2)

Ваш ответ на вопрос