2

我一直在尝试使用可配置的提供程序模型来处理我从 MEF Contrib (链接) 的 MEF 导入和导出。我已阅读 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);
        }
 }
}

测试命令.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 集合,因此我知道它正在正确访问配置信息;但是,每当我调试并尝试深入到 catalog.Parts 时,我都会收到 InvalidOperationException。

有人对我在这里出错的地方有任何经验吗?

4

2 回答 2

0

我遇到了同样的问题,无法让它工作,但这里有一些细节: ComposeParts() 似乎没有按预期工作(至少在我使用的版本中),因为它使用静态方法,基于 Reflection 来查找所有必需的导入(因此这部分似乎无法从 MEF 外部更改)。不幸的是,我们想使用 xml 配置而不是 MEF 属性。

如果您将 [Import] 属性添加到您与 ComposeParts() 一起使用的类的成员,它就会起作用。在您的情况下,这将是“程序”。在这种情况下,将找到配置文件中定义的所有导出。

我在 MEF Contrib 页面上找不到与该问题相关的任何文档或示例。在使用 ComposeParts() 的 MEF contrib 项目中也没有单元测试。一种解决方法是使用 container.GetExportedValues() 来检索值,但在这种情况下,您必须手动设置类成员。

希望有帮助。

于 2010-04-28T14:17:12.487 回答
0

如此处所述,您还需要在配置文件中使用它:

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

如果您已经拥有它,那么向我们展示InvalidOperationException您在访问时获得的堆栈跟踪可能会很有趣provider.Parts

于 2010-01-11T14:40:35.720 回答