MEFを使用して構成する次の既存のクラスを検討してくださいConsumer
。
public interface IProducer
{
void Produce();
}
[Export(typeof(IProducer))]
public class Producer : IProducer
{
public Producer()
{
// perform some initialization
}
public void Produce()
{
// produce something
}
}
public class Consumer
{
[Import]
public IProducer Producer
{
get;
set;
}
[ImportingConstructor]
public Consumer(IProducer producer)
{
Producer = producer;
}
public void DoSomething()
{
// do something
Producer.Produce();
}
}
ただし、 の作成はProducer
非常に複雑になり、コンストラクター内で行うことができなくなり、既定の動作では十分ではなくなりました。
ファクトリを導入し、プロデューサー自体でカスタム FactoryAttribute を使用して登録したいと思います。これは私が念頭に置いていることです:
[Export(typeof(IProducer))]
[Factory(typeof(ProducerFactory))]
public class Producer : IProducer
{
public Producer()
{
// perform some initialization
}
public void Produce()
{
// produce something
}
}
[Export]
public class ProducerFactory
{
public Producer Create()
{
// Perform complex initialization
return new Producer();
}
}
public class FactoryAttribute : Attribute
{
public Type ObjectType
{
get;
private set;
}
public FactoryAttribute(Type objectType)
{
ObjectType = objectType;
}
}
「新しい」コードを自分で書かなければならない場合、次のようになります。factory 属性が存在する場合はそれを使用してパーツを作成するか、デフォルトで MEF を使用して作成します。
public object Create(Type partType, CompositionContainer container)
{
var attribute = (FactoryAttribute)partType.GetCustomAttributes(typeof (FactoryAttribute), true).FirstOrDefault();
if (attribute == null)
{
var result = container.GetExports(partType, null, null).First();
return result.Value;
}
else
{
var factoryExport = container.GetExports(attribute.ObjectType, null, null).First();
var factory = factoryExport.Value;
var method = factory.GetType().GetMethod("Create");
var result = method.Invoke(factory, new object[0]);
container.ComposeParts(result);
return result;
}
}
ExportProvider を実装する方法については、次のような記事が多数あります。
ただし、例は理想的ではありません。
- アプリケーションには、依存関係や知識はなく
Producer
、 のみIProducer
です。の作成時にファクトリを登録することはできませんCompositionContainer
。 Producer
は複数のアプリケーションで再利用され、開発者は の作成時に誤ってファクトリを登録するのを忘れる可能性がありCompositionContainer
ます。- カスタム ファクトリを必要とするタイプは多数あり、 の作成時にファクトリを登録することを忘れないで
CompositionContainer
ください。
ExportProvider の作成を開始しました (これにより、ファクトリを使用して構築を実装する手段が提供されると仮定します)。
public class FactoryExportProvider : ExportProvider
{
protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition,
AtomicComposition atomicComposition)
{
// What to do here?
}
}
ただし、FactoryAttribute で定義されたファクトリ オブジェクトを使用し、そのような属性が存在しない場合は既定の作成メカニズムを使用するように MEF に指示する方法がわかりません。
これを実装する正しい方法は何ですか? MEF 2 Preview 5と .NET 4を使用しています。