有没有人使用微软的托管可扩展性框架(MEF)?有点听起来它试图成为所有人的所有事情 - 这是一个加载项管理器!这是鸭子打字!我想知道是否有人有经验,积极或消极.
我们目前正在计划为我们的下一个大项目使用通用的IoC实现ala MvcContrib.我们应该把混合物中的MEF扔掉吗?
我们的目标不是将MEF作为一个通用的IoC.考虑MEF的IoC方面的最佳方式是实现细节.我们使用IoC作为模式,因为它是解决我们希望解决的问题的好方法.
MEF专注于可扩展性.如果您认为MEF将其视为对我们平台向前发展的投资.我们未来的产品和平台将利用MEF作为增加可扩展性的标准机制.第三方产品和框架也将能够利用同样的机制.MEF的平均"用户"将创建MEF将使用的组件,并且不会在其应用程序中直接使用MEF.
想象一下,如果您希望将来扩展我们的平台,您可以在bin文件夹中删除一个dll,然后就完成了.启用MEF的应用程序将使用新扩展程序亮起.这是MEF的愿景.
这篇文章指的是Managed Extensibility Framework Preview 2.
所以,我通过MEF运行并编写了一个快速的"Hello World",如下所示.我要说这很容易深入了解.目录系统很棒,使得MEF本身非常直接.将它指向一个addin程序集的目录并让它处理其余部分是微不足道的.MEF的遗产ala Prism肯定会通过,但我认为如果它没有,那将是奇怪的,因为两个框架都是关于构图.
我认为最让我抓狂的是_container.Compose()的"魔力".如果您查看HelloMEF类,您将看到问候语字段从未被任何代码初始化,这感觉很有趣.我想我更喜欢IoC容器的工作方式,你明确要求容器为你构建一个对象.我想知道是否有某种"Nothing"或"Empty"通用初始化程序可能是有序的.即
private IGreetings greetings = CompositionServices.Empty();
至少用"东西"填充对象,直到容器组成代码运行以填充真正的"东西"为止.我不知道 - 它有点像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(); } } }