我正在使用MEF来允许用户扩展我的C#库.它到目前为止工作得很好,但是现在我正试图以我以前没见过的方式使用它.
我到目前为止看到的MEF的主要用例是:
IPerson)IPoliceman : IPerson,添加功能)ImportMany,应用程序IPerson根据必须执行的操作用于搜索正确的内容但我需要这样的事情:假设我有一个税收计算器,它接受一堆参数并根据这些参数返回估计税.我希望用户能够使用MEF创建插件来修改这些计算的完成方式.应该只能在任何时候加载一个执行此操作的插件.否则,我如何决定使用哪种替代实现?
所以基本上,我的问题归结为:通常MEF允许添加类和方法的实现.如何使用它来允许用户替换实现?
Wim*_*nen 12
通常,当您尝试覆盖应用程序中已存在的导出时,您将获得一个基数异常,[Import(typeof(IFoo)]因为MEF预计只有一个匹配的导出可用.
但是,您可以将插件放在单独的导出提供程序中并赋予其优先级.在这里,我为应用程序文件夹中的"plugins"子文件夹执行此操作:
Assembly executingAssembly = Assembly.GetExecutingAssembly();
string exeLocation = Path.GetDirectoryName(executingAssembly.Location);
string pluginPath = Path.Combine(exeLocation, "plugins");
var pluginCatalog = new DirectoryCatalog(pluginPath);
var pluginExportProvider = new CatalogExportProvider(pluginCatalog);
var appCatalog = new DirectoryCatalog(exeLocation,"*");
var appExportProvider = new CatalogExportProvider(appCatalog);
var container = new CompositionContainer(
pluginExportProvider, appExportProvider);
pluginExportProvider.SourceProvider = container;
appExportProvider.SourceProvider = container;
Run Code Online (Sandbox Code Playgroud)
传递给组合容器的导出提供程序的顺序决定了优先级:如果插件和应用程序部分都提供了导出,那么插件将获得优先级.
你所说的实际上只是看待同一问题的不同方式。答案比听起来更简单 - 对于您希望客户端能够覆盖的任何行为,只需将该行为放入插件中即可。
没有什么说你不能仅仅因为你是应用程序的作者就不能编写插件。将您的 TaxCalculator 类放入插件中,并公开一个接口,允许用户编写自己的税务计算器。在运行时,如果您加载了多个加载项,请选择不属于您的加载项。开箱即用,您将使用税务计算器插件,因此它将完全按照您期望的方式工作。如果用户创建自己的税务计算器插件并将其放入正确的目录中,则您可以使用它,从而有效地允许他们“覆盖”您的原始功能。