是否需要.NET托管托管扩展框架?

时间:2020-03-05 18:47:11  来源:igfitidea点击:

有没有人与微软的可管理扩展框架(MEF)合作过? Kinda听起来像是要把所有人都做得到。这是一个外接程序管理器!是鸭子打字!我想知道是否有人对此有正面或者负面的经验。

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

解决方案

回答

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

回答

我要说的是,它将与.NET 4.0框架中的"系统"名称空间挂在一起,我们不会做错太多。看看MEF如何演变以及汉密尔顿·韦里西莫(城堡)对MEF的方向产生什么影响将是很有趣的。

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

回答

这篇文章引用了Managed Extensibility Framework Preview 2.

因此,我经历了MEF并撰写了一个快速的" Hello World",如下所示。我要说的是,完全容易理解和理解。目录系统很棒,可以很轻松地扩展MEF本身。将其指向外接程序集的目录并让其处理其余部分很简单。 MEF的遗产ala Prism确实可以证明这一点,但我认为如果不这样做,那将是很奇怪的,因为这两个框架都是关于组合的。

我认为最困扰我的事情是_container.Compose()的"魔力"。如果查看HelloMEF类,我们将看到greetings字段从未被任何代码初始化,这简直太可笑了。我想我更喜欢IoC容器的工作方式,即我们明确要求容器为我们构建对象。我不知道某种" Nothing"或者" Empty"通用初始值设定项是否正确。 IE。

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();
        }
    }
}

回答

安迪,我相信Glenn Block在MSDN MEF论坛的这个主题中回答了许多类似这样的人(自然)问题:

CompositionContainer与传统IoC容器的比较。

在某种程度上,相对于MEF背后的主要意图(即可扩展性而不是组合性),上述Artem的答案是正确的。如果我们主要对合成感兴趣,请使用其他常见的IoC怀疑者之一。另一方面,如果我们主要关注可扩展性,那么目录,零件,元数据标记,鸭子类型和延迟加载的引入都会带来一些有趣的可能性。同样,Krzysztof Cwalina在这里解释了MEF和System.Addins如何相互关联。

回答

我们不希望MEF成为通用IoC。考虑MEF的IoC方面的最佳方法是实现细节。我们将IoC用作模式,因为它是解决我们要解决的问题的好方法。

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

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

回答

关于安迪关于MEF加载的扩展的安全性问题(很抱歉,我还没有足够的要点:)),解决此问题的地方在目录中。 MEF目录是完全可插入的,因此我们可以在加载之前编写一个自定义目录来验证程序集密钥等。如果需要,我们甚至可以使用CAS。我们正在寻找可能提供的挂钩,以使我们无需编写目录即可执行此操作。但是,当前目录的源是免费提供的。我怀疑最低限度是有人(也许在我们的团队中)会实施一个并将其扔到CodePlex的扩展/贡献项目中。

回答

鸭子类型不会在V1中提供,尽管它在当前版本中。在将来的版本中,我们将使用可插入的适配器机制替换它,在该机制中,用户可以使用鸭子类型的机制。我们之所以选择鸭子类型,是为了解决版本问题。使用Duck Typing,我们可以删除出口商和进口商之间的共享引用,从而允许合同的多个版本同时存在。

回答

这篇文章和评论中对此有更详细的讨论

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

回答

Ayende在这里也有很好的文章:http://ayende.com/Blog/archive/2008/09/25/the-managed-extensibility-framework.aspx