简体   繁体   中英

MEF Import is null

I have an Import that is not working - the object is null. Originally it was an ImportMany but I simplified it down to an Import to try to identify the issue but I haven't been successful in doing so.

I've gone through this site and Google and followed the main ideas:

  • Don't instantiate the class yourself, let MEF do it, otherwise call container.getExport() - still doesn't work
  • Put an [Export] on the class containing the [Import] property otherwise it won't be picked up as a part by the container composition process (confirmed when debugging).

My code set up is as follows (simplified for the sake of compactness):

Assembly1

public class MyBootstrapper
{
    //Automatically called by ExcelDna library, I do not instantiate this class
    public void AutoOpen()
    {
        var ac1 = new AssemblyCatalog(typeof(XLHandler).Assembly);
        var ac2 = new AssemblyCatalog(typeof(MyComponent).Assembly);

        var agc = new AggregateCatalog();
        agc.Catalogs.Add(ac1);
        agc.Catalogs.Add(ac2);

        var cc = new CompositionContainer(agc);

        try
        {
            cc.ComposeParts(this);
        }
        catch (CompositionException exception) {}
    }
}

[Export]
public class XLHandler
{
    [Import(typeof(IMyComponent))]
    public IMyComponent _component;

    public void SomeMethod()
    {
        //try to use _component but it is null
    }
}

Assembly2

public interface IMyComponent
{
    //stuff...
}

Assembly3

[Export(typeof(IMyComponent)]
public MyComponent : IMyComponent
{
    //more stuff...
}

Anybody know/have an idea as to why the _component variable in XLHandler is not injected into by the MEF container?

Do I need to Export/create an AssemblyCatalog for the Interface in Assembly2?

When importing parts, you can either use the [Import] attribute on a Property, or request it as part of the Constructor and use an [ImportingConstructor] attribute.

Any part imported using the [Import] attribute will not be available in the class's constructor

So in your case, change the XLHandler class like this:

[Export]
public class XLHandler
{
    [ImportingConstructor]
    public void SomeMethod(MyComponent component)
    {
        _component = component;
       // You can use _component, since it has already been resolved...
    }
}

In MyBootstrapper.AutoOpen you need to replace:

cc.ComposeParts(this);

with something like:

var handler = new XLHandler();
cc.ComposeParts(handler);

or:

var handler = cc.GetExportedValue<XLHandler>();

You cannot compose the parts of MyBootstrapper since it has not imports. ComposeParts does nothing.

Another approach is to add an import to MyBootstrapper . Like:

public class MyBootstrapper
{
    [Import]
    XLHandler XLHandler;

    //Automatically called by ExcelDna library, I do not instantiate this class
    public void AutoOpen()
    {
        //Leave your implementation unchanged.
    }
}

By the way MyComponent does not compile.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM