8

ユーザー オブジェクトに依存関係を挿入したいが、現在のユーザーを IoC コンテナーに配置したい状況があります。次の行を機能させたい:

kernel.Get<User>(); // Should return a new User()
kernel.Get<User>("Current"); // Should return the current user

次のようなバインディングが機能すると考えるかもしれません。

Bind<User>().ToSelf();
Bind<User>().ToMethod(LoadCurrentUser).InRequestScope().Named("Current");

もちろん、次のようになります。

Ninject.ActivationException: ユーザーのアクティブ化中にエラーが発生しました
複数の一致するバインディングが利用可能です。
アクティベーション パス:
1) 利用者へのお願い

提案:
1) User のバインドを 1 回だけ定義したことを確認します。

名前付きバインディングはそのバインディングの適用を制限しないため、エラーを理解しています。したがって、両方のバインディングが適用されます。.When*() メソッドでコンテキスト バインドを使用する必要があることは明らかですが、それを行う方法が思いつきません。名前付きインスタンスが適用されているかどうかを検出するメソッドがあるべきだと思います。何かのようなもの:

// Not valid Ninject syntax
Bind<User>().ToSelf().WhenUnnamedRequested();
Bind<User>().ToMethod(LoadCurrentUser).WhenNamedRequested().InRequestScope().Named("Current");

インターフェイス上に場所が見つからないかIRequest、要求された名前を教えてくれるプロパティです。どうすればいいですか?

4

1 に答える 1

3

この質問はメーリング リストで回答されました: http://groups.google.com/group/ninject/browse_thread/thread/cd95847dc4dcfc9d?hl=en


カーネルで Get を呼び出してユーザーにアクセスしている場合 (そうならないことを願っています)、最初のバインディングにも名前を付けて、常に名前で User にアクセスします。実際、バインディングから名前なしでインスタンスを取得する方法があります。しかし、私はこれをしないことを心からお勧めするので、ここではその方法を示しません。それでもこの方法でやりたい場合は、後でこれがどのように機能するかを説明します.

より適切で好ましい方法で実行し、ユーザーを依存関係として必要とするオブジェクトにユーザーを挿入する場合、2 つのオプションがあります。

  1. 簡単なもの: 最初のバインディングに名前を付け、パラメーターに名前付き属性を追加します。たとえば、 ctor([Named("NewUser") IUser newUser, [Named("Current")] IUser currentUser)
  2. または、実装クラスを IoC フレームワークから解放するための推奨される方法: カスタム属性を指定し、それらをパラメーターに追加します (例: ctor([NewUser] IUser newUser, [CurrentUser]IUser currentUser))。バインディングを次のように変更します。

    Bind<User>().ToSelf()
                .WhenTargetHas<NewUserAttribute>();
    Bind<User>().ToMethod(LoadCurrentUser)
                .InRequestScope()
                .WhenTargetHas<CurrentUserAttribute>();
    
于 2010-10-29T11:33:51.133 に答える