1

我正在使用 MvcContrib 的可移植区域和 MEF 构建一个插件框架,以允许将可移植区域添加为插件,而无需重新编译(只需将您的 dll 放在 bin/Modules 文件夹中)或直接引用插件项目。

在开发插件时,我有两个项目的解决方案:MyFramework 和 MyPlugin。一切正常。我有另一个解决方案,其中只有项目 MyFramework,但 MyPlugin.dll 位于 bin/Modules 文件夹中。当我使用实例化目录时

string Path = HostingEnvironment.MapPath("~/bin");
string ModulesPath = HostingEnvironment.MapPath("~/bin/Modules");
var catalog = new AggregateCatalog(
    new DirectoryCatalog(Path)
    new DirectoryCatalog(ModulesPath)
);

我可以看到 MyPlugin.dll 的程序集已加载,但未找到任何部件。我尝试使用 MEFx 转储组合状态,如下所述

string Path = HostingEnvironment.MapPath("~/bin");
string ModulesPath = HostingEnvironment.MapPath("~/bin/Modules");
var binCatalog = new DirectoryCatalog(Path);
var modulesCatalog = new DirectoryCatalog(ModulesPath);
var catalog = new AggregateCatalog(binCatalog, modulesCatalog);

using (var container = new CompositionContainer(modulesCatalog))
{
    var ci = new CompositionInfo(modulesCatalog, container);
    var stringWriter = new StringWriter();

    CompositionInfoTextFormatter.Write(ci, stringWriter);
    string compositionStateString = stringWriter.ToString();
    Console.WriteLine(s);
}

但是 compositionStateString 只是一个空字符串。

我无法理解问题的出处。由于 MyFramework 没有直接引用 MyPlugin,因此这两个项目是否编译为同一解决方案的一部分并不重要,对吧?

附加信息:我在探测路径中有 bin/Modules 。

我通过使用自定义导出属性装饰控制器来导出控制器:

[ExportModuleControllerAttribute("NotificationsController")]
public class NotificationsController : BaseController
{
    //...
}

该属性在 MyFramework 中定义如下:

[AttributeUsage(AttributeTargets.Class), MetadataAttribute]
public class ExportModuleControllerAttribute : ExportAttribute, INamedMetadata        
{
    public string[] Dependencies { get; set; }
    public string Name { get; set; }

    public ExportModuleControllerAttribute(string name, params string[] dependencies)
        : base(typeof(IController))
    {
        Dependencies = dependencies;
        Name = name;
    }
}

与 INamedMetadata 接口一样:

public interface INamedMetadata
{
    #region Properties
    string Name { get; }
    #endregion
}
4

3 回答 3

3

您如何在模块 dll 中导出类(我猜是控制器)等?让我们看看更多的代码。设置一个目录是不够的,你实际上必须告诉 mef 把东西放进去。

还要对 ci.PartDefinitions 进行计数,看看里面是否有任何东西。事实上,检查调试器中的 ci 和容器变量,看看你有什么。

另外,为什么您只检查 modulesCatalog 不应该检查目录,例如

 var ci = new CompositionInfo(catalog, container);

无论如何,希望这能为您指明正确的方向。

于 2012-06-25T22:13:16.533 回答
1

@Peter 提出了一些很好的观点。我还建议您尝试 Visual MEFX。您可以在mefcontrib-tools项目中找到它。这将让您以交互方式探索您的程序集。您可以一次添加一个,看看是否有任何导出。

这是一篇关于设置它的文章:Visual MEFX 入门

于 2012-06-26T00:56:36.830 回答
0

您需要确保已将*.pdb文件包含在启动 bin 文件夹中。

*.dll不足以满足进口。

于 2016-04-21T18:58:45.820 回答