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'.
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.