2011-09-06 25 views
9

この質問は私の前の質問のフォローアップです:Autofac: Hiding multiple contravariant implementations behind one compositeです。Autofac:入力引数と出力引数の両方で型を解決する

私は、Autofacの共分散と逆分散サポートでできることの範囲を見つけようとしています。私は、AutofacのContravariantRegistrationSourceは、inというキーワードでマークされた1つの汎用パラメータを持つ汎用インタフェースしかサポートしていないことに気付きました。これはこの機能の有用性を制限するように思われ、Autofacが共分散と反動のサポートを拡張する他の方法を持っているのだろうかと思います。

実際にアプリケーションを設計しているので、私はこれを尋ねていないことを認めなければなりません。私は故意に教育のためにオートファックの限界を見つけようとしています。私は、この設計および構成で

var builder = new ContainerBuilder(); 

builder.RegisterSource(new ContravariantRegistrationSource()); 

builder.RegisterType<ObjectToStringConverter>() 
    .As<IConverter<object, string>>(); 

var container = builder.Build(); 

たい:

public interface IConverter<in TIn, out TOut> 
{ 
    TOut Convert(TIn value); 
} 

そして、次の実装:

public class ObjectToStringConverter : IConverter<object, string> 
{ 
    string IConverter<object, string>.Convert(object value) 
    { 
     return value.ToString(); 
    } 
} 

そして次registation

だから、次のインターフェイスを検討しますできることを期待してください:

// This call succeeds because IConverter<object, string> is 
// explicitly registered. 
container.Resolve<IConverter<object, string>>(); 

// This call fails, although IConverter<string, object> is 
// assignable from IConverter<object, string>. 
container.Resolve<IConverter<string, object>>(); 

か、私は与えられた定義で、より抽象的に言えましょう:

public class A { } 
public class B : A { } 
public class C : B { } 

public class AToCConverter : IConverter<A, C> { ... } 

そして次登録:

builder.RegisterType<AToCConverter>() 
    .As<IConverter<C, A>>(); 

私は、次の呼び出しが成功することを期待する:

container.Resolve<IConverter<C, A>>(); 
container.Resolve<IConverter<B, B>>(); 
container.Resolve<IConverter<A, C>>(); 

どのようにAutofacでこれを行うことができますか?

答えて

4

私はこれがオートファックでは克服することはできないと考えていますが、これは興味深いことです。

ジェネリック型の引数を指定すると、その引数が割り当て可能なすべてのベース/インタフェースタイプを見つけることができるので、contravariant 'resolve'を実行できます。引数の型からそのサブクラスのすべてに - - それは

は反対方向に行くなど、私たちはobjectの実装を検索することができstring与え、IComparableあるので、簡単ではありません。 objectがあれば、それ以外のものを探す方法が必要です。

コンテナに登録された具体的なコンポーネントの知識を使用することができます。可能な実装を探しているすべてのコンポーネントをスキャンして後方に働きますが、これはAutofacにとってはあまり役に立ちません。なぜなら、多くの場合、コンポーネントを遅延生成するための 'プル'モデルに依存しているからです。

これはあなたが思い付くことに興味を持って、思考のための食糧であるといいと思います。

1

ContravariantRegistrationSourceは、1つの汎用パラメータを持つタイプのみを認識していることには間違いありません。 the source(現時点では約166行目)を見ると、その制限が表示されます。可能性のある候補者を提供するために登録ソースがどのように必要とされているかを見ると、制限を解除するには実装がより複雑になることが理解できます。

これは、あなたがAutofacの制限に達していることを証明するものではなく、この特定の登録ソースの制限のみと言います。読者がContravariantRegistrationSourceの実装を強化するための練習として残しておきますが、私はAutofacプロジェクトがコアに戻って受け入れることを喜んでいると確信しています。

+0

1と等しいかどうかのチェックは、反変変数の数をカウントしています。任意の数の他の(非反動的な)パラメータを依然として扱うことができる。乾杯! –

関連する問題