从不同的装配导入零件

时间:2011-11-29 12:00:00

标签: c# mef

方法

我正在使用MEF创建一个插件,如果你愿意的话,应用程序。我的MEF主持人有一个ILogger,可以公开TraceMessage(string message)。类Logger实现ILogger,并使用Export属性进行修饰,以便Logger看起来像:

[Export(typeof (ILogger))]
public class Logger : ILogger
{ }

这个想法是各种插件可以提供一个他们可以写入的中央记录器。因此,实例化将通过[Import] attribue,例如:

[Export(typeof (ILogger))]
public class Logger : ILogger
{
    private readonly IWindsorContainer _container;

    public ICloudTrace CloudTrace
    {
        get { return _container.Resolve<ICloudTrace>(); }
    }

    public Logger()
    {
        _container = new WindsorContainer(new XmlInterpreter());
    }

    public void TraceMessage(string categoryName, string componentName, string message)
    {
        CloudTrace.TraceMessage(categoryName, componentName, message);
    }
}

随后将通过Logger.TraceMessage(string message)写入日志消息。

问题

但是,这种方法在尝试解析导出时会在我的主机中抛出InvalidOperationException,并显示错误消息Sequence contains no matching element

导出在ResolveType(string commandType)中得到解决(其中commandType是执行相关插件所需的命令行参数)。 ResolveType()看起来像:

public dynamic ResolveType(string commandType)
{
   try
   {
     return this.Container.GetExports<ICommand, ICommandMetaData>()
                .First(contract => contract.Metadata.CommandType.Equals(commandType, StringComparison.OrdinalIgnoreCase))
                .Value;
    }
    catch (Exception e)
    {
       Console.WriteLine(e.message);
    }
}

我应该提一下,每个插件都有一个Execute(Dictionary<string, string> parameters),它是插件的入口点,包含此方法的类使用[Export(typeof(ICommand))] [ExportMetadata("CommandType","CommandLine Command string goes here")]属性进行修饰。

1 个答案:

答案 0 :(得分:0)

问题出在CompositionContainer构造中。目前,它只是加载命令行中指定的插件程序集,而不是执行目录扫描或加载当前正在执行的程序集。这是出于各种原因。所以:

var assemblyCatalog = new AssemblyCatalog(Assembly.LoadFrom(assemblyFile: assemblyToLoad));

其中assemblyToLoad是特定插件的.dll文件的字符串。但是,记录器位于主机中,因此需要加载主机的程序集。因此:

var assemblyCatalog = new AggregateCatalog(new AssemblyCatalog(Assembly.GetExecutingAssembly()),
                                           new AssemblyCatalog(Assembly.LoadFrom(assemblyFile: assemblyToLoad)));

解决了这个问题。 感谢@Matthew Abbott指出这一点

相关问题