2013-03-14 8 views
15

私はAutofacでデリゲートファクトリパターンを理解しようとしています。私はここでうまく説明されているキー付き()登録、とIIndex <>を使用して工場を実装する方法を知っている:Configuring an Autofac delegate factory that's defined on an abstract classfuncを使用したオートファクトデリゲートファクトリ<>

私はのFunc <>を使用してファクトリを作成できるかどうかを知りたい、と私はどのように行うのでしょう

次のサンプルのための登録:

public enum Service 
{ 
    Foo, 
    Bar 
} 

public interface FooService : IService 
{ 
    ServiceMethod(); 
} 

public interface BarService : IService 
{ 
    ServiceMethod(); 
} 

public class FooBarClient 
{ 
    private readonly IService service; 

    public FooBarClient(Func<Service, IService> service) 
    { 
     this.service = service(Service.Foo); 
    } 

    public void Process() 
    { 
     service.ServiceMethod(); // call the foo service. 
    } 
} 
+0

'IIndex <>'と 'Keyed()'を併用していますか? Autofacはこの 'Func 'を作成することはできません。 'Keyed()'や 'Named()'を使ってコンテナに登録する必要があります: 'builder.Register >(c => s => c.ResolveKeyed ); 'Delegateファクトリは、パラメータを持つ型を1つだけ作成し、パラメータに基づいて型を選択することはできません。これは、' IIndex <> 'のためです。 – nemesv

+2

IIndex <>では、避けようとしているAutofacライブラリを参照する必要があります。可能であれば、自分のDIコードをコンポジットルート(別のライブラリ)にしたい。 –

答えて

16

Autofacは、パラメータに基づいて異なる型を返すことができますどのあなたのためにこれFunc<Service, IService>を構築することができません。これはIIndex<>が対象です。

しかし、あなたがしたくない場合は/あなたがKeyedまたはNamedの助けを借りて、このファクトリ関数を作成して、コンテナにあなたの工場を登録することができIIndex<>を使用することはできません。

あなただけ使用していないのはなぜ
var builder = new ContainerBuilder(); 
builder.RegisterType<FooBarClient>().AsSelf(); 
builder.RegisterType<FooService>().Keyed<IService>(Service.Foo); 
builder.RegisterType<BarService>().Keyed<IService>(Service.Bar); 

builder.Register<Func<Service, IService>>(c => 
{ 
    var context = c.Resolve<IComponentContext>(); 
    return s => context.ResolveKeyed<IService>(s); 
}); 
+0

おかげでnemesv!その期待どおりの作業! 1つの質問、パフォーマンスに何か違いがありますか? - IIndex vs Func? –

+0

IIndexがどのように実装されているのか、どのような種類のチャーチやパフォーマンスの最適化があるのか​​わかりません。埋め込みを確認するか、シナリオに合わせてパフォーマンステストを作成して比較する必要があります。 – nemesv

+2

私はちょうど理由のバージョンでそれを試みましたが、それは私に 'ObjectDisposedException'を与えました...私はデリゲートの中で' new Foo'を呼び出すことによってこれを解決しました(これはbiiiig nogoです!) –

関連する問題