有没有人使用微软的托管可扩展性框架(MEF)?有点听起来它试图成为所有人的所有事情 - 这是一个加载项管理器!这是鸭子打字!我想知道是否有人有过积极或消极的经历。
我们目前正在计划为我们的下一个大项目使用通用的IoC实现ala MvcContrib。我们应该把混合物中的MEF扔掉吗?
答案 0 :(得分:33)
我们的目标不是让MEF成为一个通用的IoC。考虑MEF的IoC方面的最佳方式是实现细节。我们使用IoC作为模式,因为它是解决我们希望解决的问题的好方法。
MEF专注于可扩展性。如果您认为MEF将其视为对我们平台向前发展的投资。我们未来的产品和平台将利用MEF作为增加可扩展性的标准机制。第三方产品和框架也将能够利用同样的机制。 MEF的平均“用户”将创建MEF将使用的组件,并且不会在其应用程序中直接使用MEF。
想象一下,如果您希望将来扩展我们的平台,您可以在bin文件夹中删除一个dll,然后就完成了。启用MEF的应用程序将使用新扩展程序亮起。这就是MEF的愿景。
答案 1 :(得分:8)
这篇文章涉及Managed Extensibility Framework Preview 2。
所以,我有一个MEF的运行并写了一个快速的“Hello World”,如下所示。我要说这很容易深入了解。目录系统很棒,使得MEF本身非常直接。将它指向一个addin程序集的目录并让它处理其余部分是微不足道的。 MEF的遗产ala Prism肯定会通过,但我认为如果它没有,那将是奇怪的,因为两个框架都是关于构图。
我认为最让我抓狂的是_container.Compose()的“魔力”。如果您查看HelloMEF类,您将看到问候语字段从未被任何代码初始化,这感觉很有趣。我想我更喜欢IoC容器的工作方式,你明确要求容器为你构建一个对象。我想知道是否有某种“Nothing”或“Empty”通用初始化程序可能是有序的。即。
private IGreetings greetings = CompositionServices.Empty<IGreetings>();
至少用“东西”填充对象,直到容器组合代码运行以填充真正的“东西”为止。我不知道 - 它有点像Visual Basic的Empty或Nothing关键字,我一直不喜欢它。如果其他人对此有一些想法,我想听听他们的意见。也许这只是我需要克服的东西。它标有一个很大的[导入]属性,所以它不像是一个完整的神秘或任何东西。
控制对象生存期并不明显,但默认情况下一切都是单例,除非您向导出的类添加[CompositionOptions]属性。那就是你指定Factory或Singleton。很高兴看到Pooled在某个时候添加到此列表中。
我不清楚鸭子打字功能是如何工作的。它似乎更像是在创建对象时的元数据注入而不是鸭子类型。看起来你只能添加一个额外的鸭子。但就像我说的那样,我还不清楚这些功能是如何运作的。希望我能回来并在以后填写。
我认为对由DirectoryPartCatalog加载的DLL进行阴影复制是个好主意。现在,一旦MEF获得它们,DLL就会被锁定。这还允许您添加目录观察程序并捕获更新的插件。那会很可爱......
最后,我担心插件DLL的可信度以及MEF在部分信任环境中的行为方式。我怀疑使用MEF的应用程序需要完全信任。将addins加载到自己的AppDomain中也可能是谨慎的做法。我知道它有点像System.AddIn,但它可以在用户插件和系统插件之间进行非常清晰的分离。
好的 - 足够的喋喋不休。这是MEF和C#中的Hello World。享受!
using System;
using System.ComponentModel.Composition;
using System.Reflection;
namespace HelloMEF
{
public interface IGreetings
{
void Hello();
}
[Export(typeof(IGreetings))]
public class Greetings : IGreetings
{
public void Hello()
{
Console.WriteLine("Hello world!");
}
}
class HelloMEF : IDisposable
{
private readonly CompositionContainer _container;
[Import(typeof(IGreetings))]
private IGreetings greetings = null;
public HelloMEF()
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
_container = new CompositionContainer(catalog);
var batch = new CompositionBatch();
batch.AddPart(this);
container.Compose(batch);
}
public void Run()
{
greetings.Hello();
}
public void Dispose()
{
_container.Dispose();
}
static void Main()
{
using (var helloMef = new HelloMEF())
helloMef.Run();
}
}
}
答案 2 :(得分:4)
关于Andy关于MEF加载的扩展的安全性的问题(抱歉我还没有足够的分数:)),解决这个问题的地方在目录中。 MEF目录是完全可插入的,因此您可以在加载之前编写用于验证程序集键等的自定义目录。如果你愿意,你甚至可以使用CAS。我们正在考虑提供钩子,以便您无需编写目录即可完成此操作。但是,当前目录的来源是免费提供的。我怀疑最低限度是某人(可能在我们的团队中)将实现一个并将其放在CodePlex上的扩展/ contrib项目中。
答案 3 :(得分:4)
鸭子打字不会在V1中发货,尽管它在当前的下降中。在未来的drop中,我们将用可插拔的适配器机制替换它,其中一个可以挂钩鸭子打字机制。我们查看duck typing的原因是为了解决版本控制方案。使用Duck Typing,您可以删除出口商和进口商之间的共享参考,从而允许多个版本的合同并存。
答案 4 :(得分:2)
Andy,我相信Glenn Block在MSDN MEF论坛的这个主题中回答了许多人(自然)问题:
Comparison of CompositionContainer with traditional IoC Containers。
在某种程度上,Artem的上述答案相对于MEF背后的主要意图是正确的,这是可扩展性而非组合。如果您主要对构图感兴趣,那么请使用其他常见的IoC嫌疑人之一。另一方面,如果您主要关注可扩展性,那么目录,部件,元数据标记,鸭子打字和延迟加载的引入都会带来一些有趣的可能性。此外,Krzysztof Cwalina在解释MEF和System.Addins如何相互关联方面发挥了作用here。
答案 5 :(得分:2)
答案 6 :(得分:1)
这不是注射控制容器。它是插件支持框架。
答案 7 :(得分:1)
我会说,鉴于它将脱离.NET 4.0 Framework中的“系统”命名空间,你不会走得太远。看看MEF如何演变以及Hamilton Verissimo(Castle)对MEF方向的影响将会很有趣。
如果它像鸭子一样嘎嘎叫,它可能只是当前一群IoC容器的一部分......
答案 8 :(得分:0)
在这篇文章和评论中对此进行更详细的讨论
http://mikehadlow.blogspot.com/2008/09/managed-extensibility-framework-why.html