Reputation: 3494
I am having a problem with extending some existing C# code.
There is an instance of a manager class exported from one class. It is successfully imported into several other classes using:
[Import]
private Manager manager = null;
I have added the same code to a new class. It compiles well, but at runtime the reference is always null.
I am obviously missing something.
What I'd really like to see is the minimum code (two classes) needed to do an import. It doesn't have to do anything except create and export an object (preferably not a string nor a simple value) in one class and show it is non-null when imported to another class. (I've been getting lost in the details of other examples trying to show functionality rather than just a usable syntax.)
Please note that I need to see an example using [Import], not [Import(type)].
Thanks.
Upvotes: 1
Views: 2731
Reputation: 554
manager must be a property. try
[Import]
private Manager manager { get; set; }
Upvotes: -1
Reputation: 32505
I'm pretty sure this will work:
public class SampleClass
{
[Import]
private Manager manager; //Setting it to null is redundant.
}
[Export]
public class Manager
{
}
You'll also need to setup your container. There are frameworks that make it easier to wireup everything, but if not. It's not difficult:
At the start of your application you'll need to fill in your catalog:
//http://mef.codeplex.com/wikipage?title=Using%20Catalogs
var catalog = new AggregateCatalog();
//Add AssemblyCatalogs (Single) or DirectoryCatalogs (Multiple)
catalog.Catalogs.Add(new AssemblyCatalog(typeof(IManager).Assembly));
catalog.Catalogs.Add(new DirectoryCatalog(@"myimports\"));
//Don't do this (including the same assembly twice)
//catalog.Catalogs.Add(new AssemblyCatalog(typeof(Manager).Assembly));
var container = new CompositionContainer(catalog);
container.composeParts(this);
But, you should really take advantage of interfaces for importing/exporting.
public class SampleClass
{
[Import]
private IManager Manager;
}
[InheritedExport]
public interface IManager { }
public class Manager : IManager { }
Now, as far as stating a name and type, that is not necessary, but it's good if you plan on having similar exports that you need to distinguish.
public class SomeClass
{
//This is for the specific AdvancedManager
[Import("AdvancedManager", typeof(IManager))]
private IManager AdvancedManager;
//This is for the specific SimpleManager
[Import("SimpleManager", typeof(IManager))]
private IManager SimpleManager;
//If you don't mark it as ImportMany this will fail because now there
//are 2 non-specific IManager exports.
[ImportMany]
private ICollection<IManager> AllManagers;
}
[InheritedExport]
public interface IManager { }
//This will export out as an IManager and a specifically named IManager
[Export("AdvancedManager", typeof(IManager))]
public class AdvancedManager : IManager { }
//This will export out as an IManager and a specifically named IManager
[Export("SimpleManager", typeof(IManager))]
public class SimpleManager : IManager { }
Upvotes: 4