MEF =可能会遇到挫折? [英] MEF = may experience frustration?

查看:150
本文介绍了MEF =可能会遇到挫折?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新



由于我试图让MEF在我的应用程序中工作,我遇到更多的地方,只是不知道为什么当我期望它不会自动创建我的图书馆。我想这一切都回到了里德所说的需要MEF创造一切的一切。所以现在,我有一个XML阅读器类,需要使用我的CandySettings,但即使它的ICandySettings属性具有[Import]属性,它也不会被导入。首先我发现[Import]在静态上不起作用,所以我改变了这一点。但之后,它仍然没有奏效。我认为这是因为我手动创建了XML阅读器对象,MEF希望我做的就是[导入] XML阅读器,这意味着我现在也必须有一个接口。



这几乎就像使用IoC(或至少使用MEF),这是一个全无关系的事情。你不能在这里和那里任意使用它,因为最终你要注入属性的任何类也需要由MEF创建。



请更正我,如果我错了!






原始帖子



嗯,这还不错啊:)但是,在Reed指出,MEF作为IoC的潜在替代品(到目前为止看起来还不错)之前,我确实有问题。



考虑以下模型:
alt text http://bit.ly/9W0sHt



如你所见,我有一个应用程序,这个程序使用的是插件(whoops,错过了该关联!)。应用程序和插件都需要使用类型为CandySettings的对象,该对象可以在另一个程序集中找到。



我首先尝试在MEF中使用ComposeParts方法,但是唯一的办法就是在插件代码中做这样的事情。

  var container = new CompositionContainer(); 
container.ComposeParts(this,new CandySettings());

但这没有任何意义,因为我为什么要创建CandySettings的实例插件?它应该在应用程序但是如果我把它放在应用程序代码中,那么即使我在插件中使用了[Import]和[CandySettings]中的[Export],插件也不会神奇地弄清楚如何获取ICandySettings。 EDIT (可能是因为我应该从App中调用ComposeParts(),然后传递插件?)



使用MEF的 DirectoryCatalog ,因为这样就允许插件在构造时扫描当前文件夹中的所有程序集,并自动导入标有[Import]属性的所有内容。所以它看起来像这样,并且可能在每个插件中:

  var catalog = new DirectoryCatalog( 。); 
var container = new CompositionContainer(catalog);
container.ComposeParts(this);

这完全非常棒,但我不禁想到这不是MEF的意图要使用?

解决方案

这里的诀窍是你想让MEF为你创建你的插件。 >

您将这样做的方法是让您的应用程序自己编写,并指定插件类型:

  class PluginRepository 
{
[ImportMany(typeof(IPlugin))]
IEnumerable< IPlugin>插件{get;组; }
}

如果你这样做,并让MEF撰写你的仓库类, MEF 将构建对象。然后,它会自动构建它们,因此 ICandySettings 将无需任何干预即可组合。



如果MEF没有为您构建,您只需手动组合一个对象。


UPDATE

As I've tried to get MEF working throughout my application, I'm coming across more an more places where I just don't get why it's not automatically creating my library when I expect it to. I think it all comes back to what Reed was saying about needing MEF to create everything. So right now, I have an XML reader class that needs to use my CandySettings, but even though its ICandySettings property has the [Import] attribute, it doesn't get imported. First I found out that [Import] doesn't work on statics, so I changed this. But after that it still didn't work. I think it's because I manually create the XML reader object, and what MEF wants me to do instead is to [Import] the XML reader... which means that I now have to have an interface for that as well.

It's almost like using IoC (or for MEF, at least), it's an all-or-nothing affair. You can't just arbitrarily use it here and there, because ultimately whatever class you want to inject properties into also needs to be created by MEF.

Please correct me if I am wrong!


Original post

Well, it's not THAT bad yet. :) But I do have questions after Reed has pointed me at MEF as a potential alternative to IoC (and so far it does look pretty good).

Consider the following model: alt text http://bit.ly/9W0sHt

As you can see, I have an App, and this app uses Plugins (whoops, missed that association!). Both the App and Plugins require usage of an object of type CandySettings, which is found in yet another assembly.

I first tried to use the ComposeParts method in MEF, but the only way I could get this to work was to do something like this in the plugin code.

var container = new CompositionContainer();
container.ComposeParts(this, new CandySettings());

But this doesn't make any sense, because why would I want to create the instance of CandySettings in the plugin? It should be in the App. But if I put it in the App code, then the Plugin doesn't magically figure out how to get at ICandySettings, even though I am using [Import] in the plugin, and [Export] in CandySettings. EDIT (probably because I should be calling ComposeParts() from the App and then passing it the plugin?)

The way I did it was to use MEF's DirectoryCatalog, because this allows the plugin, when constructed, to scan all of the assemblies in the current folder and automagically import everything that is marked with the [Import] attribute. So it looks like this, and potentially in every plugin:

var catalog = new DirectoryCatalog(".");
var container = new CompositionContainer(catalog);
container.ComposeParts(this);

This totally works great, but I can't help but think that this is not how MEF was intended to be used?

解决方案

The "trick" here is that you want to have MEF create your plugins for you.

The way you'll do this is to have your Application compose itself, with the Plugin types specified:

class PluginRepository
{
    [ImportMany(typeof(IPlugin))]
    IEnumerable<IPlugin> Plugins { get; set; }
}

If you do this, and have MEF Compose your "repository" class, MEF will construct the objects. It'll then automatically Compose those as it constructs them, so ICandySettings will get composed without any intervention for you.

You only need to manually "compose" an object if MEF isn't constructing it for you.

这篇关于MEF =可能会遇到挫折?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆