2011-11-29 66 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雅培指出這一點