4

一般的な制約を尊重するようにninjectバインディングを設定することは可能ですか?

例えば:

interface IFoo { }
interface IBar { }
interface IRepository<T> { }

class FooRepository<T> : IRepository<T> where T : IFoo { }
class BarRepository<T> : IRepository<T> where T : IBar { }

class Foo : IFoo { }
class Bar : IBar { }

class Program
{
    static void Main(string[] args)
    {
        IKernel kernel = new StandardKernel();

        // Use this binding only where T : IFoo
        kernel.Bind(typeof(IRepository<>)).To(typeof(FooRepository<>));

        // Use this one only where T : IBar
        kernel.Bind(typeof(IRepository<>)).To(typeof(BarRepository<>));

        var fooRepository = kernel.Get<IRepository<Foo>>();
        var barRepository = kernel.Get<IRepository<Bar>>();
    }
}

このコードをそのまま呼び出すと、複数のアクティベーションパスの例外が発生します:-

IRepository {Foo}のアクティブ化中にエラーが発生しました:複数の一致するバインディングが使用可能です。

Tの値を条件とするバインディングを設定するにはどうすればよいですか?理想的には、すでに定義しているので、ターゲットタイプから制約を取得してもらいたいのですが、バインディングで再度定義する必要がある場合は、これも受け入れられます。

4

1 に答える 1

1

おそらくよりクリーンな解決策がありますが、それはWhen コンテキストバインディングメソッドといくつかのリフレクションで確実に機能します:

// Use this binding only where T : IFoo
kernel.Bind(typeof(IRepository<>)).To(typeof(FooRepository<>))
   .When(r => typeof(IFoo).IsAssignableFrom(r.Service.GetGenericArguments()[0]));

// Use this one only where T : IBar
kernel.Bind(typeof(IRepository<>)).To(typeof(BarRepository<>))
  .When(r =>  typeof(IBar).IsAssignableFrom(r.Service.GetGenericArguments()[0]));
于 2012-10-08T12:36:42.717 に答える