、ここでの例です:私たちは、メタデータの契約を定義することができる
public interface ILogger
{
void Log(string message);
}
[Export(typeof(ILogger)), ExportMetadata("Name", "Console")]
public class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine(message);
}
}
[Export(typeof(ILogger)), ExportMetadata("Name", "Debug")]
public class DebugLogger : ILogger
{
public void Log(string message)
{
Debug.Print(message);
}
}
はその契約およびそれらの実装例を考えると、我々はLazy<T, TMetadata>
ようなタイプをインポートすることができます。
public interface INamedMetadata
{
string Name { get; }
}
MEFはExportMetadata
属性値を具体的な実装としてTMetadata
(この例では01)として投影するため、メタデータの実装の作成について心配する必要はありません。上記で、私は次の例を作成することができます。そのサンプルクラスで
public class Logger
{
[ImportMany]
public IEnumerable<Lazy<ILogger, INamedMetadata>> Loggers { get; set; }
public void Log(string name, string message)
{
var logger = GetLogger(name);
if (logger == null)
throw new ArgumentException("No logger exists with name = " + name);
logger.Log(message);
}
private ILogger GetLogger(string name)
{
return Loggers
.Where(l => l.Metadata.Name.Equals(name))
.Select(l => l.Value)
.FirstOrDefault();
}
}
が、私は
Lazy<ILogger, INamedMetadata>
インスタンスとして、多くのインスタンスをインポートしています。
Lazy<T,TMetadata>
を使用すると、値にアクセスする前にメタデータにアクセスできます。上記の例では、私は
name
引数を使用して、使用する適切なロガーを選択しています。
インポート時にクラスをインスタンス化するのが適切でない場合は、ExportFactory<T,TMetadata>
を使用すると、必要に応じて型のインスタンスをスピンアップできます。 (ExportFactory
は、.NET 4.0のSilverlightのバージョンに含まれていますが、グレン・ブロックは、デスクトップ/ウェブ用にソースコードon codeplexを投げました。
を、私はそれが役に立てば幸い。
おかげでジョシュが、私は契約名を使用しようとしていました私の問題を解決しましたが、輸出部品で契約名を使用すると、ImportManyを使用できません。輸入部品を一緒にインポートするImportManyを使用する方法はありますか? – Ray
一般的に、ImportManyとImportManyを簡単に組み合わせることはできませんあなたがインポートを持っていて、複数のエクスポートがある場合、同じ例外が発生します。ただし、コンストラクタでImportManyを実行して、別のロジックに基づいてインポートされたものを選択できます。 – Josh