2012-02-19 4 views
1

Iは、(簡単にするために除去非関連コード)以下のような単純なコンソールアプリケーションを有するMEFおよびAssemblyCatalog/AggregateCatalog

[ImportMany(typeof(ILogger))] 
    public IEnumerable<ILogger> _loggers {get;set;} 

    public interface ILogger 
    { 
     void Write(string message); 
    } 

    [Export(typeof(ILogger))] 
    public class ConsoleLogger : ILogger 
    { 
     public void Write(string message) 
     { 
      Console.WriteLine(message); 
     } 
    } 

    [Export(typeof(ILogger))] 
    public class DebugLogger : ILogger 
    { 
     public void Write(string message) 
     { 
      Debug.Print(message); 
     } 
    } 

カタログを初期化コードが

(1) var catalog = new AggregateCatalog(); 
(2) catalog.Catalogs.Add(new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory)); 
(3) //var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); 

var container = new CompositionContainer(catalog); 
var batch = new CompositionBatch(); 
batch.AddPart(this); 
container.Compose(batch); 

未満であるカタログ場合ログラインには何もロードされていません カタログがトラフライン3に初期化されていれば、両方のロガーが_loggerにロードされました

What ' AggregateCatalogアプローチの問題?

おかげ

答えて

0

この問題が見つかりました。

デフォルトでは、ディレクトリカタログ(パス)の検索はDLL内でのみ行われ、テストプログラムはコンソールアプリケーションでした。エクスポートはEXE(DLLではない)にあり、ロードされませんでした。

一方、AssemblyCatalog(Assembly.GetExecutingAssembly())は、明らかに現在のアセンブリ(EXE)からのエクスポートをロードしました。

解決策は、DirectoryCatalog(path、searchPattern)のもう一方のコンストラクタを使用し、2番目のparamに "*。*"を使用することです。そしてそれは動作します

0

それはあなたがそれを使用しているように動作する必要があります。

ただし、2行目ではDirectoryCatalogを作成し、3行目でAssemblyCatalogを作成しています。 2行目を2行に変更すると、期待通りに機能しますか?

catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly())); 
+0

ありがとう。しかし、DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory)という行が、appのbinフォルダ内のすべてのDLLからのカタログエクスポートに追加されることを期待しています(これは実際にある時点で必要なものです)。 AssemblyCatalogとは異なり、AssemblyCatalogは現在のアセンブリからのエクスポートを追加するだけです。どのようにすべてのDLLの輸出を探すには? – bzamfir