سؤال

I'm building a plugin framework using MvcContrib's portable areas and MEF to allow adding portable areas as plugins without needing to recompile (just drop your dll in the bin/Modules folder) or have a direct reference to the plugin project.

While developing the plugin I have a solution with two projects: MyFramework and MyPlugin. Everything works just fine. I have another solution that just has the project MyFramework in it, but MyPlugin.dll is in the bin/Modules folder. When I instantiate a catalog using

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

I can see that the assembly for MyPlugin.dll is loaded, but no Parts are found. I tried using MEFx to dump composition state as described here like so:

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

but compositionStateString is just an empty string.

I'm having trouble understanding where the issue is coming from. Since MyFramework has no direct reference to MyPlugin, it shouldn't matter if the two projects are compiled as part of the same solution, right?

Additional info: I have bin/Modules in the probing path.

I'm exporting controllers by decorating them with a custom export attribute:

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

That attribute is defined in MyFramework like so:

[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;
    }
}

As is the INamedMetadata interface:

public interface INamedMetadata
{
    #region Properties
    string Name { get; }
    #endregion
}
هل كانت مفيدة؟

المحلول

@Peter makes some good points. I'd also recommend that you try Visual MEFX. You can find it in the mefcontrib-tools project. This will let you interactively explore your assemblies. You can add them one at a time and see if there is anything exported.

Here's an article on getting it setup: Getting Started with Visual MEFX

نصائح أخرى

How are you exporting classes (I'm guessing Controllers) etc in your module dlls? lets see some more code. It's not enough to setup a catalog you actually have to tell mef to put things in it.

Also do a count on ci.PartDefinitions to see if you have anything in there. In fact inspect the ci and the container variables in the debugger and see what you have got in them.

Also why are you only inspecting modulesCatalog shouldn't you be inspecting catalog eg

 var ci = new CompositionInfo(catalog, container);

Anyhow hope this points you in the right direction.

You need to make sure you have included your *.pdb files in the startup bin folder.

*.dll is not sufficient to satisfy imports.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top