So, I'm playing around with MEF -- kind of trying a classic IoC thing -- injecting a logging class. I have it working, but it is not working the way I expected it to work. Can you tell me where I'm off track?
I think that my problem is that I'm bootstrapping MEF incorrectly. I expected to Export a logger, and Import it to inject it into any class that wanted to use it.
What I'm finding is that for any class that wants to use it, I have to new up a container, load the catalogs, and call ComposeParts(). (which is actually a lot harder than just calling MyEventLogFactory.GetEventLog()). (I expected to have to bootstrap MEF once, on program init, but I seem to have to do it for every class that has in import)
Here's my bootstrap code (in the startup of a Console app):
static void Main(string[] args)
{
InitMefContainer();
var test = new TestHarness();
test.RunTest();
Console.ReadLine();
}
private static void InitMefContainer()
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(typeof(EventLogFactory).Assembly));
catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly));
var container = new CompositionContainer(catalog);
container.ComposeParts();
_Container = container;
}
Then my TestHarness class looks like this:
public class TestHarness
{
[Import(typeof(IEventLog))]
public IEventLog EventLog { get; set; }
public void RunTest()
{
// did not expect to need to do this, but EventLog is null if I don't
Program._Container.ComposeParts(this);
this.EventLog.Write(some test event stuff);
}
}
My problem is that EventLog is always null. -- Unless, I repeat all of the MefInitialization code that Program.Main executed (or, if I make the container that Program created a public static, I can call _Container.ComposeParts(this);
So, my question: what is the right way to bootstrap MEF so that it satisfies all of my imports? Is it common practice to have a public static container and call Container.Compose(this)? (or to use AStaticContainer.GetExportedValue, sort of like you would use ServiceLocator.GetService()? inside all of my classes -- I definitely have not seen that in any sample code out there.