Модель поставщика контента MEF, Не Импортирующая Детали

StackOverflow https://stackoverflow.com/questions/2034555

  •  19-09-2019
  •  | 
  •  

Вопрос

Я пытался использовать настраиваемую модель поставщика для обработки моего импорта и экспорта MEF из MEF Contrib (Ссылка).Я прочитал документацию Codeplex и сообщение в блоге Code Junkie (Ссылка);однако, похоже, я не могу заставить контейнер создавать детали.Где я иду не так, как надо?

Program.cs Программа.cs

namespace MEFTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            p.Run();
        }

        // [ImportMany("command", typeof(IHelp))]
        public IEnumerable<IHelp> Commands { get; set; }

        void Run()
        {
            Compose();

            foreach(IHelp cmd in Commands)
            {
                Console.WriteLine(cmd.HelpText);
            }

            Console.ReadKey();
        }

        void Compose()
        {
            var provider = new ConfigurableDefinitionProvider("mef.configuration");
            var catalog = new DefinitionProviderPartCatalog<ConfigurableDefinitionProvider>(provider);
            var container = new CompositionContainer(catalog);
            container.ComposeParts(this);
        }
 }
}

Тестовая команда.cs

namespace MEFTest
{
    //[Export("command", typeof(IHelp))]
    public class TestCommand : IHelp
    {
        private string _helpText = "This is a test.";

        public string CommandName
        {
            get { return "Test"; }
        }

        public string HelpText
        {
            get { return _helpText; }
        }
    }
}

Раздел App.Config (Приложение.Конфигурация):

<mef.configuration>
 <parts>
  <part type="MEFTest.TestCommand, MEFTest">
   <exports>
    <export contract="IHelp" />
   </exports>
  </part>
  <part type="MEFTest.Program, MEFTest">
   <imports>
    <import member="Commands" contract="IHelp" />
   </imports>
  </part>
 </parts>
</mef.configuration>

Я не получаю никаких ошибок сборки, и она работает нормально, если я переключаюсь на типичную систему на основе атрибутов, которая является частью ядра MEF (с соответствующим каталогом тоже).Program.Commands в приведенном выше примере всегда имеет значение NULL.Я попытался просто использовать единственное свойство вместо коллекции и получить те же результаты.

Когда я отлаживаю, я могу получить поставщика.Коллекция деталей, поэтому я знаю, что он правильно обращается к информации о конфигурации;однако я получаю исключение InvalidOperationException всякий раз, когда я выполняю отладку и пытаюсь выполнить детализацию в catalog.Части.

У кого-нибудь есть какой-нибудь опыт относительно того, где я здесь ошибаюсь?

Это было полезно?

Решение

Как задокументировано здесь, вам также нужно это в вашем конфигурационном файле:

<configSections>
  <section
    name="mef.configuration"
    type="MefContrib.Models.Provider.Definitions.Configurable.PartCatalogConfigurationSection, MefContrib.Models.Provider" />
</configSections>

Если у вас это уже есть, то, возможно, было бы интересно показать нам трассировку стека InvalidOperationException что вы получаете при доступе provider.Parts.

Другие советы

У меня были те же проблемы, и я не смог заставить его работать, но вот некоторые детали:Похоже, что ComposeParts() работает не так, как ожидалось (по крайней мере, в версии, которую я использовал), потому что он использует статические методы, основанные на отражении, для поиска всех необходимых импортов (поэтому кажется, что эта часть не может быть изменена извне MEF).К сожалению, мы хотим использовать конфигурацию xml, а не атрибуты MEF.

Это работает, если вы добавляете атрибуты [Import] к членам класса, который вы используете с ComposeParts().В вашем случае это было бы "Programm".В этом случае будут найдены все экспортные данные, определенные в файле конфигурации.

Я не смог найти никакой документации или примеров на странице содержимого MEF, относящихся к этой проблеме.Также в проекте MEF contrib нет unittest, который использует ComposeParts() .Обходным решением было бы использовать container.GetExportedValues() для извлечения значений, но в этом случае вам придется устанавливать элементы classes вручную.

Надеюсь, это поможет.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top