2011-11-29 23 views
1

方法从不同的装配

导入部分,我使用MEF创建一个插件,nable,如果你愿意,应用。我的MEF主机有​​,它暴露了TraceMessage(string message)Logger类实现​​和装饰着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

感谢您的更新。这听起来像是无法找到零件或元数据。你有一个'Command'的例子和一个对'ResolveType'的调用。另外,你能否确认你能看到容器中的零件?我也会使用'FirstOrDefault'而不是'First'来承担更多的错误,并且从方法签名中删除'dynamic',因为你知道你将返回一个'ICommand'的实例。 –

+0

啊哈!这是'CompositionContainer'的一个问题。 'AssemblyCatalog'没有加载'Logger'程序集! 感谢您的提示 – aateeque

回答

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雅培指出这一点