MEF可以加载组件但不加载任何零件

时间:2012-06-25 21:59:51

标签: asp.net asp.net-mvc plugins mef mvccontrib

我正在使用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来转储组合状态,如here所描述的那样:

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,因此将两个项目编译为同一解决方案的一部分并不重要,对吗?

其他信息: 我在probing path中有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
}

3 个答案:

答案 0 :(得分:3)

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

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

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

 var ci = new CompositionInfo(catalog, container);

无论如何希望这能指出你正确的方向。

答案 1 :(得分:1)

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

以下是关于设置它的文章:Getting Started with Visual MEFX

答案 2 :(得分:0)

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

*.dll不足以满足进口。