尝试学习 MEF 时遇到困难

发布于 2024-11-11 16:26:53 字数 2772 浏览 1 评论 0 原文

我一直在尝试自学 MEF,从本教程开始:

http://blogs.msdn.com/b/brada/archive/2008/09/29/simple-introduction-to-composite-applications-with-the-managed-extensions-framework.aspx< /a>

MEF 现在的工作方式与本教程中的工作方式相比存在一些差异。一个区别是 CompositionBatch 对象;然而,我想我理解所做的改变。

不过,我似乎无法理解的一个区别是,虽然教程说我应该能够通过更改属性的返回类型来处理 0/1/多次导入,但我无法在实践中实现这一点。下面我将粘贴给我一个错误的代码;谁能告诉我为什么这不起作用以及我应该做什么?

我最终将使用 MEF 创建一个基于插件的应用程序,通过将实现特定接口的不同 .dll 文件放入目录中,该应用程序将在运行时添加不同的功能。我想我会为此使用 DirectoryCatalog,但我想我需要首先了解这个障碍。

namespace MessinWithMef
{
    class Program
    {
        [Import]
        public IEnumerable<string> Message { get; set; }

        public void Run()
        {
            var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            var batch = new CompositionBatch();

            batch.AddPart(this);

            var container = new CompositionContainer(catalog);
            container.Compose(batch);

            foreach (var s in Message)
            {
                Console.WriteLine(s);
            }

            Console.ReadKey();
        }

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

    public class SimpleHello
    {
        [Export]
        public string Message
        {
            get
            {
                return "Hello world!";
            }
        }
    }

    public class ExtraHello
    {
        [Export]
        public string OtherMessage
        {
            get
            {
                return "Hi there!";
            }
        }
    }
}

这是错误的文本:

The composition remains unchanged. The changes were rejected because of the following error(s): The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.

1) No valid exports were found that match the constraint '((exportDefinition.ContractName == "System.Collections.Generic.IEnumerable(System.String)") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "System.Collections.Generic.IEnumerable(System.String)".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))', invalid exports may have been rejected.

Resulting in: Cannot set import 'MessinWithMef.Program.Message (ContractName="System.Collections.Generic.IEnumerable(System.String)")' on part 'MessinWithMef.Program'.
Element: MessinWithMef.Program.Message (ContractName="System.Collections.Generic.IEnumerable(System.String)") -->  MessinWithMef.Program

I have been trying to teach myself MEF, starting with this tutorial:

http://blogs.msdn.com/b/brada/archive/2008/09/29/simple-introduction-to-composite-applications-with-the-managed-extensions-framework.aspx

There are some differences from the way MEF works now compared to the way it seems to work in this tutorial. One difference is the CompositionBatch object; however, I think I understand the changes that were made.

One difference I can't seem to understand, though, is that whereas the tutorial says I should be able to handle 0/1/multiple imports by changing the return type of a property, I can't make this work in practice. Below I will paste the code that is giving me an error; can anyone enlighten me as to why this doesn't work and what I should do instead?

I will eventually be using MEF to create a plugin-based application that will have different functionality added at runtime by dropping different .dll files that implement a certain interface into a directory. I think I'll be using the DirectoryCatalog for that, but I think I need to understand this hurdle first.

namespace MessinWithMef
{
    class Program
    {
        [Import]
        public IEnumerable<string> Message { get; set; }

        public void Run()
        {
            var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            var batch = new CompositionBatch();

            batch.AddPart(this);

            var container = new CompositionContainer(catalog);
            container.Compose(batch);

            foreach (var s in Message)
            {
                Console.WriteLine(s);
            }

            Console.ReadKey();
        }

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

    public class SimpleHello
    {
        [Export]
        public string Message
        {
            get
            {
                return "Hello world!";
            }
        }
    }

    public class ExtraHello
    {
        [Export]
        public string OtherMessage
        {
            get
            {
                return "Hi there!";
            }
        }
    }
}

Here's the text of the error:

The composition remains unchanged. The changes were rejected because of the following error(s): The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.

1) No valid exports were found that match the constraint '((exportDefinition.ContractName == "System.Collections.Generic.IEnumerable(System.String)") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "System.Collections.Generic.IEnumerable(System.String)".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))', invalid exports may have been rejected.

Resulting in: Cannot set import 'MessinWithMef.Program.Message (ContractName="System.Collections.Generic.IEnumerable(System.String)")' on part 'MessinWithMef.Program'.
Element: MessinWithMef.Program.Message (ContractName="System.Collections.Generic.IEnumerable(System.String)") -->  MessinWithMef.Program

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

用心笑 2024-11-18 16:26:53

如果您想解析多个匹配的导出,则必须使用[ImportMany]

请注意,在插件类型的场景中,您可能需要使用 ExportMetadata,然后决定您实际要实例化的插件。然后,您可以执行以下操作:

[ImportMany]
IEnumerable<Lazy<IPlugin, IPluginMetadata>> _possiblePlugins;

现在您的代码可以枚举可能的插件,检查元数据,然后决定是否实例化每个延迟导入。

You have to use [ImportMany] if you want to resolve multiple matching Exports.

Note that, in a Plugin type of scenario, you'll probably want to use ExportMetadata and then decide which of the Plugins you actually want to instantiate. You would then do something like:

[ImportMany]
IEnumerable<Lazy<IPlugin, IPluginMetadata>> _possiblePlugins;

Now your code can enumerate the possible plugins, examine the metadata, and then decide whether or not to instantiate each Lazy import.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文