Модель поставщика MEF Contrib не импортирует детали

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

Программа.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);
        }
 }
}

TestCommand.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. Я попытался просто использовать единственное свойство вместо коллекции и получить те же результаты.

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

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


person JamesEggers    schedule 09.01.2010    source источник


Ответы (2)


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

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

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

person Wim Coenen    schedule 11.01.2010

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

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

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

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

person Bernhard Kircher    schedule 28.04.2010