【问题标题】:Whither Managed Extensibility Framework for .NET?.NET 的托管可扩展性框架在哪里?
【发布时间】:2010-09-07 17:18:08
【问题描述】:

有没有人使用过 Microsoft 的托管可扩展性框架 (MEF)?有点像它试图成为所有人的一切 - 它是一个加载项管理器!这是鸭子打字!我想知道是否有人对此有经验,无论是积极的还是消极的。

我们目前正计划在我们的下一个大型项目中使用通用 IoC 实现 ala MvcContrib。我们应该把 MEF 加入其中吗?

【问题讨论】:

    标签: .net mef


    【解决方案1】:

    我们的目标不是让 MEF 成为一个通用的 IoC。考虑 MEF 的 IoC 方面的最佳方式是实现细节。我们使用 IoC 作为一种模式,因为它是解决我们要解决的问题的好方法。

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

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

    【讨论】:

      【解决方案2】:

      这篇文章是指托管可扩展性框架预览版 2。

      所以,我浏览了 MEF 并快速编写了一个“Hello World”,如下所示。我得说这很容易深入和理解。目录系统非常棒,让 MEF 本身的扩展变得非常简单。将它指向插件程序集的目录并让它处理其余部分是微不足道的。 MEF 的传统 ala Prism 肯定会体现出来,但我认为如果不这样做会很奇怪,因为这两个框架都是关于组合的。

      我认为最让我印象深刻的是 _container.Compose() 的“魔力”。如果您查看 HelloMEF 类,您会发现 greetings 字段从未被任何代码初始化,这感觉很有趣。我认为我更喜欢 IoC 容器的工作方式,即明确要求容器为您构建对象。我想知道某种“Nothing”或“Empty”通用初始值设定项是否合适。即

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

      这至少会用“某物”填充对象,直到容器组合代码运行以用真正的“某物”填充它。我不知道——它有点像 Visual Basic 的 Empty or Nothing 关键字,我一直不喜欢。如果其他人对此有一些想法,我想听听他们的意见。也许这是我需要克服的。它标有一个大胖子[进口]属性,所以它不是一个完全的谜或什么的。

      控制对象的生命周期并不明显,但默认情况下一切都是单例,除非您将 [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();
              }
          }
      }
      

      【讨论】:

      • 我最近玩过 MEF 预览版 4,他们对代码进行了一些清理。 AggregatingComposablePartCatalog 现在只是 AggregateCatalog 等等。恕我直言,这是一场大胜利
      【解决方案3】:

      关于安迪关于 MEF 加载的扩展的安全性问题(对不起,我还没有足够的分数 :)),解决这个问题的地方是目录。 MEF 目录是完全可插入的,因此您可以编写一个自定义目录,在加载之前验证程序集密钥等。如果您愿意,您甚至可以使用 CAS。我们正在考虑可能提供挂钩,让您无需编写目录即可执行此操作。但是,当前目录的源代码是免费提供的。我怀疑至少有人(可能在我们的团队中)会实现一个并将其放入 CodePlex 上的扩展/贡献项目中。

      【讨论】:

        【解决方案4】:

        Duck 打字不会在 V1 中发布,尽管它在当前的 drop 中。在未来的下降中,我们将用一种可插入的适配器机制来替换它,在这种机制中,人们可以挂上鸭子类型机制。我们查看鸭子类型的原因是为了解决版本控制场景。使用 Duck Typing,您可以删除出口商和进口商之间的共享引用,从而允许多个版本的合同并存。

        【讨论】:

          【解决方案5】:

          Andy,我相信 Glenn Block 在 MSDN MEF 论坛上的这个帖子中回答了很多人(自然)这样的问题:

          Comparison of CompositionContainer with traditional IoC Containers

          在某种程度上,相对于 MEF 背后的主要意图,Artem 的回答是正确的,即可扩展性而不是组合。如果您主要对组合感兴趣,请使用其他常见的 IoC 嫌疑人之一。另一方面,如果您主要关心可扩展性,那么引入目录、部件、元数据标记、鸭子类型和延迟加载都会带来一些有趣的可能性。此外,Krzysztof Cwalina 对 here 进行了解释 MEF 和 System.Addins 如何相互关联。

          【讨论】:

            【解决方案6】:

            【讨论】:

              【解决方案7】:

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

              【讨论】:

                【解决方案8】:

                我会说,鉴于它会挂起 .NET 4.0 框架中的“系统”命名空间,因此您不会错得太远。看看 MEF 如何发展以及 Hamilton Verissimo(城堡)对 MEF 的发展方向有何影响,将会很有趣。

                如果它像鸭子一样嘎嘎叫,它可能只是当前 IoC 容器群的一部分......

                【讨论】:

                  【解决方案9】:

                  在这篇文章和 cmets 中对此进行了更详细的讨论

                  http://mikehadlow.blogspot.com/2008/09/managed-extensibility-framework-why.html

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2011-08-02
                    • 1970-01-01
                    相关资源
                    最近更新 更多