在MEF中导出/导入接口

时间:2014-01-16 00:20:44

标签: c# .net mef

请参阅以下代码。使用MEF我创建了一个管理器对象和一个插件,它可以按原样导入IQueryEngine。

但是,当我在插件中调用方法_queryEngine.Get()时,我得到一个MissingMethodException,就像在QueryEngine的具体实现中没有实现该方法一样,但是它已经实现了。我相信这与ManagedElementDTO类有关,但我不知道该怎么做。

任何人都可以了解正在发生的事情吗?

我有一个界面:

public interface IQueryEngine
{
    ManagedElementDTO Get();
}

实施:

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

此引擎在经理中声明:

[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;
    }
}

和插件:

[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!
    }
}

1 个答案:

答案 0 :(得分:3)

要导出QueryEngine类型,您应该执行以下操作

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

现在在插件类中导入它应该像

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

我不太确定您尝试对[Export]字段上的IQueryEngine做了什么。你应该能够完全删除