Question

Please refer to the following code. Using MEF I have created a manager object and a plug-in, which imports the IQueryEngine as it should.

However, when I call the method _queryEngine.Get() in the plugin, I get a MissingMethodException, like the method isn't implemented in the concrete implementation of QueryEngine, however it is implemented. I believe that this has to do with the ManagedElementDTO class, but I am not sure what to do here.

Can anyone shed some light on what is going on?

I have an interface:

public interface IQueryEngine
{
    ManagedElementDTO Get();
}

And the implementation:

public class QueryEngine : IQueryEngine
{
    public ManagedElementDTO Get() 
    {
        return new ManagedElementDTO();
    }
}

This engine is declared in a manager:

[Export]
public class ProviderSupervisor : ISupervisor
{
    [Export("QueryEngine")]
    private IQueryEngine _queryEngine;

    [ImportMany(typeof(IProviderModule))]
    private IEnumerable<IProviderModule> _providers; 

    public ProviderSupervisor(IStore store)
    {
        _queryEngine = new QueryEngine();

        CreateContainer();
    }

    /// <summary>
    /// Creates the composition container and composes the parts.
    /// </summary>
    /// <returns>The container.</returns>
    private CompositionContainer CreateContainer()
    {
        try
        {
             var catalog = new AggregateCatalog();

             var directory = GetProviderDirectory();

             if (directory.Exists)
             {
                 catalog.Catalogs.Add(new DirectoryCatalog(directory.FullName));
             }

             var container = new CompositionContainer(catalog);
             container.ComposeParts(this);

             return container;
        }
        catch (Exception)
        {
            // TODO: Log Error
            throw;
        }
    }

    private static DirectoryInfo GetProviderDirectory()
    {
        var location = ConfigurationSupervisor.GetInstance().ProviderLocation;

        if (!string.IsNullOrWhiteSpace(location))
        {
            var providerLocation = new DirectoryInfo(Environment.ExpandEnvironmentVariables(location));

            if (providerLocation.Exists)
            {
                return providerLocation;
            }
        }

        // Use the current assembly location as the default.
        var exeLocation = new FileInfo(Assembly.GetExecutingAssembly().Location);

        return exeLocation.Directory;
    }
}

and the plug-in:

[Export(typeof(IProviderModule))]
public class Provider : IProviderModule, IDisposable
{
    private IQueryEngine _queryEngine;

    #region Properties

    /// <summary>
    /// Gets or sets the query engine.
    /// </summary>
    [Import("QueryEngine", typeof(IQueryEngine), RequiredCreationPolicy = CreationPolicy.Shared)]
    public IQueryEngine QueryEngine
    {
        get { return _queryEngine; }
        set
        {
            _queryEngine = value;
        }

    }

    public void InvokeQueryEngine()
    {
        var item = _queryEngine.Get(); // Exception!
    }
}
Was it helpful?

Solution

In order to export your QueryEngine type you should be doing the following

[Export(typeof(IQueryEngine))]
public class QueryEngine : QueryEngine 

Now in the plugin class importing it should be as simple as

[Import(typeof(IQueryEngine), RequiredCreationPolicy = CreationPolicy.Shared)]
public IQueryEngine QueryEngine
{
    get { return _queryEngine; }
    set
    {
        _queryEngine = value;
    }
}

I'm not quite sure what you are attempting to do with the [Export] on the IQueryEngine field. You should be able to delete that entirely

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