2008-09-03 75 views
21

有没有人与微软的Managed Extensibility Framework(MEF)合作过?有点听起来它试图成为所有人的所有东西 - 这是一个插件管理器!这是鸭子打字!我想知道,如果有人有经验,积极或消极。.NET的托管扩展框架?

我们目前正在计划在下一个大项目中使用通用IoC实现ala MvcContrib。我们应该把MEF扔进混合体中吗?

回答

33

我们不打算让MEF成为一个通用的IoC。考虑MEF的IoC方面的最佳方式是实现细节。我们使用IoC作为模式,因为它是解决我们正在寻求解决的问题的好方法。

MEF专注于可扩展性。当你想到MEF将它视为推动我们平台发展的投资时。我们未来的产品和平台将利用MEF作为增加扩展性的标准机制。第三方产品和框架也将能够利用这种相同的机制。 MEF的平均“用户”将编写MEF将消耗的组件,并且不会直接在其应用程序中使用MEF。

想象一下,当您希望将来扩展我们的平台时,您将一个dll放入bin文件夹中即可完成。启用了MEF的应用程序随着新的扩展程序亮起。这是MEF的愿景。

1

这不是注射控制容器。它是插件支持框架。

1

我想说它会挂在.NET 4.0框架中的'系统'命名空间,你不能犯太多错误。看看MEF如何演变以及Hamilton Verissimo(Castle)对MEF的方向有何影响将会很有趣。

如果它叫起来像鸭子,那么它也许会是IoC容器的当前羊群的一部分...

8

这个职位是指托管扩展框架预览2.

所以,我通过了MEF并写下了一个快速的“Hello World”,下面将会介绍它。我必须说,深入并理解它非常容易。目录系统非常好,使得MEF本身非常简单。把它指向一个插件程序集的目录并让它处理剩下的东西是很简单的。 MEF的遗产ala Prism肯定会透露,但我认为如果不是这样,它会很奇怪,因为这两个框架都是关于构图的。

我认为我最喜欢的东西是_container.Compose()的“魔术”。如果你看看HelloMEF类,你会发现greetings字段永远不会被任何代码初始化,这只是感觉很有趣。我认为我更喜欢IoC容器的工作方式,您明确要求容器为您构建对象。我想知道是否有某种“Nothing”或“Empty”泛型初始化器可能会按顺序排列。即

private IGreetings greetings = CompositionServices.Empty<IGreetings>(); 

即至少填充有“东西”,直到该对象作为容器组成代码运行与真正的“什么”,以填充它。我不知道 - 它记录了一些我一直不喜欢的Visual Basic的Empty或Nothing关键字。如果其他人对此有一些想法,我想听听他们。也许这是我需要解决的问题。它被标记为一个胖胖的[Import]属性,所以它不像是一个完整的神秘或任何东西。

控制对象的生命周期并不明显,但默认情况下,除非向导出的类添加[CompositionOptions]属性,否则默认情况下所有东西都是单例。那让我们指定Factory或Singleton。很高兴看到Pooled在某个时候添加到此列表中。

我不太清楚鸭子打字功能的工作原理。它看起来更像是创建对象时的元数据注入,而不是鸭子打字。它看起来像只能添加一个额外的鸭子。但就像我说的,我还不清楚这些功能的工作原理。希望我能回来并在以后填写。

我认为这将是一个好主意,以阴影复制由DirectoryPartCatalog加载的DLL。现在,一旦MEF抓住它们,DLL就会被锁定。这也可以让你添加一个目录观察器并捕获更新的插件。这将是非常可爱的...

最后,我担心插件DLL的可信度如何,以及MEF如何在部分信任环境中运行。我怀疑使用MEF的应用程序需要完全信任。在他们自己的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(); 
     } 
    } 
} 
+1

我最近与MEF预览4打球,他们已经有些清理了代码。 AggregatingComposablePartCatalog现在只是AggregateCatalog等,所有围绕一个大赢家恕我直言 – 2009-02-18 02:06:29

2

安迪,我相信格伦座回答很多人的(自然)的问题,如这些在这个线程了在MSDN MEF论坛:

Comparison of CompositionContainer with traditional IoC Containers

在某种程度上,Artem上面的回答与MEF背后的主要意图是正确的,这是可扩展性而不是组成性。如果您主要对构图感兴趣,那么请使用其他常见的IoC嫌疑犯之一。另一方面,如果您主要关心可扩展性,那么引入目录,部件,元数据标签,鸭子打字和延迟加载都会产生一些有趣的可能性。另外,Krzysztof Cwalina在解释MEF和System.Addins如何相互关联时拍摄了here

4

关于Andy对MEF加载扩展的安全性问题(抱歉,我还没有足够的积分:)),解决此问题的地方在目录中。 MEF目录完全可插入,因此您可以在加载之前编写一个自定义目录来验证程序集密钥等。如果您愿意,您甚至可以使用CAS。我们正在研究可能提供的钩子,使您无需编写目录即可完成此操作。但是,当前目录的来源可以免费获取。我怀疑最低限度是某人(可能在我们的团队中)将执行一个并将其放入CodePlex上的扩展/ contrib项目中。

4

鸭子打字不会在V1中出货,虽然它在当前的下降。在未来的下降中,我们将用可插入的适配器机制替换它,其中可以挂钩鸭子打字机制。我们研究duck typing的原因是为了解决版本控制的情况。通过鸭子打字,您可以删除出口商和进口商之间的共享参考,从而允许多个版本的合同并排生活。在这个岗位,并在此