1

MVC2プロジェクトをMVC3にアップグレードし、NuGetライブラリパッケージリファレンスを使用してninjectをインストールしました。これによりappstartクラスが作成され、次のコードを使用してIMembershipServiceクラスを挿入しました。

public static void RegisterServices(IKernel kernel) {
        kernel.Bind<IMembershipService>().To<AccountMembershipService>();
    }

これは、たとえば私のHomeControllerでうまく機能します。

public class HomeController : Controller
{
    public IMembershipService MembershipService { get; set; }

    public HomeController() : this(null) { }

    public HomeController(IMembershipService service)
    {
        MembershipService = service;
    }

ただし、私はBaseControllerを使用しています。基本クラスのほぼ同じコードは機能しなくなりました。

public class BaseController : Controller
{
    public IMembershipService MembershipService { get; set; }
    public UserService UserService { get; set; }

    public BaseController() : this(null, null) { }

    public BaseController(IMembershipService service, UserService userService)
    {
        MembershipService = service;
        UserService = userService ?? new UserService();
    }

ベースコントローラーのコンストラクターに割り込むと、サービスはNULLになります。私はIOCにNinjectを使用したことがないので、おそらく答えは明らかですが、なぜそれが私のAccountMembershipControllerを基本クラスに注入しないのでしょうか。何が違うのかわかりませんが、継承の余分なレベルがどういうわけかNinjectを台無しにしている可能性があることはわかっています。

4

2 に答える 2

5

あなたのHomeControllerはBaseControllerではなくControllerから派生していますか?また、物事をnullとして設定するBaseControllerのデフォルトコンストラクターがあります。なぜあなたはそれを持っているのですか?私はそれらのデフォルトのコンストラクターを取り除くことから始めます。デフォルトのコンストラクターは必要ありません。

于 2010-11-10T20:42:59.367 に答える
1

私自身も同じ問題に遭遇しました。コードが次のようになっていると仮定します。

public HomeController : BaseController
{

}

public BaseController : Controller
{
    public IMembershipService MembershipService { get; set; }

    public MembershipService() { }

    public MembershipService(IMembershipService service)
    {
        MembershipService = service;
    }
}

何らかの理由で、NinjectHomeControllerは、コンストラクターが1つしかない、つまりデフォルトのパラメーターなしのコンストラクターであると考えています。すべてをに入れるとHomeController、注入可能なコンストラクターを見つけることができますが、それを基本クラスに分解します。何らかの理由で、オーバーロードされたコンストラクターがあるかどうかを確認するために基本クラスを調べません。これには2つの修正があります。

  1. デフォルトのコンストラクターを削除します。これは、コンストラクターを強制的に挿入するため(単体テスト時にコントローラーを手動で作成する場合など)、私の推奨されるソリューションですが、欠点は、すべてのサブクラスにコンストラクターを実装する必要があることです。
  2. [Injectデフォルトのコンストラクターを維持しますが、すべての注入可能なプロパティに]属性を追加します。

    public BaseController : Controller
    {
        [Inject] public IMembershipService MembershipService { get;set; }
        // rest is the same
    }
    

Ninjectはこの方法でプロパティを正しく注入しますが、Ninjectがパラメーターなしのコンストラクターを呼び出すことに注意してください。

于 2010-11-10T20:47:59.893 に答える