Question

I am having trouble getting MEF to satisfy an import and could use some help.

Unfortunately, the problem only manifests in a production code base. I tried to simplify the problem so I could post an example and see where my lack of understanding is, but the simplified version worked. So this is either I am missing the difference (and I have done my best to look thoroughly at the two), or the complexity is needed to reproduce.

I have a WPF application consuming .NET 4.5 class libraries and portable class libraries (targeting .net 4.5 and windows 8 store apps). I do not yet have a windows 8 store application, but it is planned (thus the headache). I am using MEF 2 that I pulled off of NuGet recently:

  <package id="Microsoft.Composition" version="1.0.20" targetFramework="portable-net45+win" />

I guess what I am looking for is some advice on how to debug this, since I will not be able to post the actual code. Most of the online advice I can find on how to debug doesn't seem to work with MEF 2, at least not this PCL-compatible version. The following is my simplified version but, again, this version works.

namespace Portable.Contracts
{
    public interface IExportable
    {
        string Name { get; }
    }
}

namespace Desktop
{
    [Export(typeof(IExportable))]
    public class Exported : IExportable
    {
        public string Name
        {
            get { return "Exported"; }
        }
    }
}

namespace Portable
{
    public class Importer
    {
        [Import]
        public IExportable Exportable { get; set; }

        public Importer()
        {
            MEFLoader.ResolveImports(this);
        }

        public string Name { get { return Exportable.Name; } }
    }
}

namespace Portable
{
    public class MEFLoader
    {
        private static CompositionHost Container { get; set; }
        public static void SetContainer(CompositionHost container)
        {
            Container = container;
        }
        public static void ResolveImports(object target)
        {
            if(Container != null)
            {
                Container.SatisfyImports(target);
            }
        }
    }
}

namespace WPFApp
{
    public partial class App : Application
    {
        public App()
        {
            var container = new ContainerConfiguration()
                .WithAssembly(typeof(Exported).Assembly)
                .CreateContainer();
            MEFLoader.SetContainer(container);

            var importer = new Importer();
            var importedName = importer.Name;
        }
    }
}

importedName does get the value "Exported". In my production code I get a CompositionFailedException with detail:

Additional information: Missing dependency 'UserInformation' on 'MainWindowViewModel'.

Was it helpful?

Solution

I found my root cause.

My .NET 4.5 assemblies were getting at MEF using:

using System.ComponentModel.Composition;

while my PCL assembles were using:

using System.Composition;

Updating everything to System.Composition solved the problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top