10

私はインターフェースを持っています:

public interface IService
{
    void DoStuff(int parm1, string parm2, Guid gimmeABreakItsAnExampleK);
}

次のように、「ディスパッチャー」シャッフルメソッドがの複数のインスタンスを呼び出すことができるように、Ninject(v3)バインディングを構成したいと思いますIService

public sealed class DispatcherService : IService
{
    private IEnumerable<IService> _children;

    public DispatcherService(IEnumerable<IService> children)
    {
        this._children = children.ToList();
    }

    public void DoStuff(int parm1, string parm2, Guid gimmeABreakItsAnExampleK)
    {
        foreach(var child in this._children)
        {
            child.DoStuff(parm1, parm2, gimmeABreakItsAnExampleK);
        }
    }
}

ただし、このように見える私のバインディングは、実行時に例外をスローして、循環依存を示します。

this.Bind<IService>().To<DispatcherService>();

this.Bind<IService>().To<SomeOtherService>()
    .WhenInjectedExactlyInto<DispatcherService>();
this.Bind<IService>().To<YetAnotherService>()
    .WhenInjectedExactlyInto<DispatcherService>();

これは可能ですか?もしそうなら、私は何を間違っていますか?忍者はこの周期的な依存関係の運命から逃れることができますか?

4

4 に答える 4

2

ディスパッチャがIServicesのリストをパラメータとして受け取る唯一のIServiceである場合、これは機能します(私はテストしました)。

kernel.Bind<IService>().To<DispatcherService>().When(x => x.IsUnique);
this.Bind<IService>().To<SomeOtherService>()
    .WhenInjectedExactlyInto<DispatcherService>();
this.Bind<IService>().To<YetAnotherService>()
    .WhenInjectedExactlyInto<DispatcherService>();

Whenこの場合に句が機能する理由は、コンストラクターがサービスの単一インスタンスを呼び出すときに、のIsUniqueフィールドがIRequestに設定されるためです。を呼び出すtrueので、値はをアクティブ化するときです。これにより、循環依存が発生するのを防ぎます。DispatcherServiceIEnumerablefalseDispatcherService

実際、DispatcherServiceをそれ自体に注入しようとしないようにカーネルに指示する正しい方法は機能します(これは潜在的に有用な例にすぎません)。

編集:循環依存を単純に短絡するより明確な方法は次のように見えます:

kernel.Bind<IService>().To<DispatcherService>().When(
   request => request.Target.Member.DeclaringType != typeof (DispatcherService));
于 2012-10-16T03:36:21.943 に答える
1

私はNinjectAPIにあまり精通していないことを認めなければなりませんが、これでうまくいくと思います。

kernel.Bind<IService>().To<DispatcherService>();   

kernel.Bind<IEnumerable<IService>>().ToMethod(() => new IService[]
{
    kernel.Get<SomeOtherService>(),
    kernel.Get<YetAnotherService>(),
});
于 2012-10-11T21:39:28.263 に答える
1

DispatcherServiceのIServiceを削除してIDispatcherServiceと呼び、呼び出されたサービス(レシーバー)にIServiceを実装させてみませんか?

于 2012-10-15T15:39:50.263 に答える
0

2つのサブセット(ディスパッチャーまたは受信者のいずれか)を、一方を名前付きバインディングにすることで分離し、名前を(NamedAttributeまたは配線内で)一方を他方にフィー​​ドする方法として使用できます。

于 2012-10-12T09:22:29.993 に答える