MEF 是一件全有还是全无的事情吗?

发布于 2024-08-29 17:32:43 字数 605 浏览 6 评论 0原文

最近我对 MEF 有一些疑问,但这是一个大问题——它真的像看起来那样要么全有要么全无吗?

我的基本应用程序结构只是一个应用程序、几个旨在成为单例的共享库和几个不同的插件(可能实现不同的接口)。应用程序加载插件,应用程序和所有插件都需要访问共享库。

我在 MEF 的第一次尝试相当成功,尽管我一路上犯了一些愚蠢的错误,因为我尝试了很多不同的事情,有时我感到困惑。但最后,昨晚我用 MEF、一些共享库和一个插件运行了我的小型测试应用程序。

现在我将转向我已经描述过的目标应用程序。令人有点担心的是多个插件部分。

我现有的应用程序已经通过使用反射支持具有不同接口的多个插件。我需要能够唯一地标识每个插件,以便用户可以选择一个插件并获得该插件公开的预期行为。问题是我还不知道如何做到这一点......但这是另一个问题的主题。

理想情况下,我能够采用现有的插件加载器并按原样使用它,同时依靠 MEF 进行共享库解析。问题是,我似乎无法让 MEF 加载它们(即调用 ComposeParts() 时出现 CompositionException),除非我也使用 MEF 加载插件。如果我这样做,那么我需要知道如何在加载它们时跟踪它们,以便用户可以从插件列表中选择一个。

您在尝试混合和匹配这些方法方面有哪些经验?

I've had a few questions about MEF recently, but here's the big one -- is it really all-or-nothing, as it appears to be?

My basic application structure is simply an app, several shared libraries that are intended to be singletons, and several different plugins (which may implement different interfaces). The app loads the plugins, and both the app and all plugins need to access the shared libraries.

My first go at MEF was fairly successful, although I made some stupid mistakes along the way because I was trying so many different things, I just got confused at times. But in the end, last night I got my smallish test app running with MEF, some shared libraries, and one plugin.

Now I'm moving onto the target app, which I already described. And it's the multiple plugins part that has be a bit worried.

My existing application already supports multiple plugins with different interfaces by using Reflection. I need to be able to uniquely identify each plugin so that the user can select one and get the expected behavior exposed by that plugin. The problem is that I don't know how to do this yet... but that's the topic of a different question.

Ideally, I'd be able to take my existing plugin loader and use it as-is, while relying on MEF to do the shared library resolution. The problem is, I can't seem to get MEF to load them (i.e. I get a CompositionException when calling ComposeParts()) unless I also use MEF to load the plugin. And if I do this, well... then I need to know how to keep track of them as they get loaded so the user can select one from a list of plugins.

What have your experiences been with trying to mix and match these approaches?

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

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

发布评论

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

评论(1

琉璃梦幻 2024-09-05 17:32:43

MEF 旨在让您轻松加载插件程序集。如果您可以控制插件(我的意思是您可以添加 MEF 导出属性),则无需保留自己的使用反射的插件加载器。 MEF 会为您完成这一切。

话虽如此,MEF 与其他技术的“混合和匹配”当然是可能的。听起来您的问题是,如果您使用自己的插件加载器,则不会将这些插件添加到 MEF 容器中。因此,对于尝试导入所选插件的部件,您会收到 CompositionException 异常。

要将使用您自己的代码加载的插件添加到 MEF 容器,您可以使用 ComposeExportedValue,如下所示:

container.ComposeExportedValue<IPlugin>(selectedPlugin);

编辑: 我明白您现在所说的“所有或没有什么”。您的问题是,为了能够使用 MEF 导入零件,您还需要使用 MEF 构造对象。然后,这个问题会级联到通常创建该对象的对象,等等,一直到应用程序根。

为了避免这种“全有或全无”的影响,您可以通过将 MEF 容器公开为全局变量(即静态字段)来妥协。这样,类就可以访问 MEF 容器并从中提取导出,例如通过在构造函数中调用 Program.Container.GetExportedValue()

edit2:如果您有一个不是由 MEF 构造的对象,则有两种方法将其添加到容器中。

第一个是调用 container.ComposeExportedValue(myObject);

第二种是在属性 getter 中返回对象,然后使用 [Export(typeof(SomeType))] 属性标记属性本身。

MEF is designed to let you easily load plugin assemblies. If you have control over the plugins (by which I mean that you can add MEF export attributes) then there is no need to keep your own plugin loader which uses reflection. MEF does all that for you.

That being said, "mixing and matching" MEF with other technologies is certainly possible. It sounds like your problem is that if you use your own plugin loader, you don't add those plug-ins to the MEF container. As a result, you get a CompositionException for parts which try to import the selected plug-in.

To add a plugin that you loaded with your own code to the MEF container, you can use the ComposeExportedValue like this:

container.ComposeExportedValue<IPlugin>(selectedPlugin);

edit: I see what you mean now by "all or nothing". Your problem is that in order to be able to import parts with MEF, you also need to construct the object with MEF. This problem then cascades to the object which normally created that object, etc. all the way to the application root.

To avoid this "all or nothing" effect, you can compromise by exposing the MEF container as a global variable (i.e. static field). That way, classes can access the MEF container and pull exports from it, e.g. by calling Program.Container.GetExportedValue<MyDependency>() in the constructor.

edit2: If you have an object that was not constructed by MEF, then there are two ways to add it to the container.

The first is to call container.ComposeExportedValue<IMyContractType>(myObject);.

The second is to return the object in a property getter, and then mark the property itself with an [Export(typeof(SomeType))] attribute.

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