Как я могу имитировать функцию legitedexport в mef2

Я использую MEF2 и читаю несколько уроков по MEF 1 и MEF 2.

Лучший из тех, что я нашел до сих пор, это: http://www.codeproject.com/Articles/366583/MEF-Preview-Beginners-Guide

Несмотря на то, что экспорт действительно работал, я действительно хочу сделать это, используя стиль атрибутов, потому что использование InheritedExport на интерфейсах кажется гораздо более удобным, чем переходить назад и вперед между интерфейсом, который я объявляю, и моим соглашением о контейнерах.

Это фрагмент моего кода:

        var convention = new ConventionBuilder();
        convention.ForTypesDerivedFrom<IMainTabsControl>().Export<IMainTabsControl>();
        convention.ForTypesDerivedFrom<IShell>().Export<IShell>().Shared();
        // here is where i am struggeling.
        convention.ForTypesMatching(type => typeof (ICrawlerKeyProvider).IsAssignableFrom(type)).Export(builder => builder.AsContractType(typeof(bool)));

        var configuration = new ContainerConfiguration();
        MefContainer = configuration.WithAssemblies(new []{ Assembly.GetExecutingAssembly(),  }, convention).CreateContainer();

Итак, есть 3 варианта:

  • я не могу найти переименованную функцию в MEF 2
  • я не использую правильный метод
  • я упускаю что-то очевидное

Насколько я могу сказать, это должно быть довольно легко:

  • проверить тип для (пользовательского) атрибута,
  • извлечь желаемый тип экспорта для типа, который содержит желаемый атрибут
  • закончить экспорт

Но с ForTypesMatching я не могу делать то, что хочу, потому что нет никакой информации о типе, доступной для переменной построителя.

Пытаюсь ли я сделать что-то, что, как ни странно, невозможно в MEF 2, но было возможно в MEF 1?

Обновления:

Интересно почитать: http://blog.slaks.net/2014-11-16/mef2-roslyn-visual-studio-compatibility/

1 ответ

Атрибут:

public class ExportAsAttribute : Attribute
{
    public Type ContractType { get; set; }

    public string ContactName { get; set; }

    public ExportAsAttribute(Type contractType)
    {
        ContractType = contractType;
    }

    public ExportAsAttribute(Type contractType, string contactName)
    {
        ContactName = contactName;
        ContractType = contractType;
    }
}

Код конвенции:

        var allTypes = GetAllAssemblies().SelectMany(d => d.ExportedTypes);
        foreach (var type in allTypes)
        {
            var attr = type.GetCustomAttribute<ExportAsAttribute>(true);
            if (attr != null)
            {
                foreach (var derivedType in allTypes.Where(d => !d.IsAbstract && !d.IsInterface && type.IsAssignableFrom(d)))
                {
                    if (string.IsNullOrEmpty(attr.ContactName))
                    {
                        convention.ForType(derivedType).Export(config => config.AsContractType(attr.ContractType));
                    }
                    else
                    {
                        convention.ForType(derivedType).Export(config => config.AsContractType(attr.ContractType).AsContractName(attr.ContactName));
                    }
                }
            }
        }
Другие вопросы по тегам