2

I'm trying to set up Ninject for the first time. I've got an IRepository interface, and a Repository implementation. I'm using ASP.NET MVC, and I'm trying to inject the implementation like so:

public class HomeController : Controller
{
    [Inject] public IRepository<BlogPost> _repo { get; set; }

    public ActionResult Index()
    {
        ViewData["Message"] = "Welcome to ASP.NET MVC!";

        var b = new BlogPost
                    {
                        Title = "My First Blog Post!",
                        PostedDate = DateTime.Now,
                        Content = "Some text"
                    };

        _repo.Insert(b);

        return View();
    }

    // ... etc
}

And here's Global.asax:

public class MvcApplication : NinjectHttpApplication
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            "Default",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        );

    }

    protected override void OnApplicationStarted()
    {
        RegisterRoutes(RouteTable.Routes);
    }

    protected override IKernel CreateKernel()
    {
        IKernel kernel = new StandardKernel(new BaseModule());
        return (kernel);
    }
}

And here's the BaseModule class:

   public class BaseModule : StandardModule
    {
        public override void Load()
        {
            Bind<IRepository<BlogPost>>().To<Repository<BlogPost>>();
        }
    }

When I browse to the Index() action, though, I get "Object reference not set to an instance of an object" when trying to use _repo.Insert(b). What am I leaving out?

4

2 に答える 2

3

Ninject 1.0 には、そのままでは MVC サポートがありませんでした。Web に散在する Ninject 1.0 で MVC を使用するさまざまな方法があります。

MVC サポートを含む Ninject トランクから最新のコードを取得することをお勧めします。次に、アプリケーションの開始点として以下を使用します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using DemoApp.Models;
using Ninject.Core;
using Ninject.Framework.Mvc;

namespace DemoApp
{
    public class MvcApplication : NinjectHttpApplication
    {
        protected override void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default",                                              // Route name
                "{controller}/{action}/{id}",                           // URL with parameters
                new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
            );
        }

        protected override IKernel CreateKernel()
        {
            return new StandardKernel(new BaseModule(), new AutoControllerModule(Assembly.GetExecutingAssembly()));
        }
    }
}

元の実装と比べて強調すべき点がいくつかあります...

  • Ninject には、NinjectHttpApplication という2 つの 実装名があります。1 つは Ninject.Framework.Web に、もう 1 つは Ninject.Framework.Mvc にあります。後者には保護された RegisterRoutes() メソッドが含まれているため、前者を使用しているようです。
  • Ninject にコントローラー作成へのフックを与える方法が必要です。これは ControllerBuilder を使用して行われます。Ninject.Framework.Mvc.NinjectHttpApplication は NinjectControllerFactory を登録します。Ninject 1.0 を使用している場合は、自分で用意する必要があります。
  • コントローラーをコンテナーに登録する必要があります。手動で行うこともできますが、最新のコード プロバイダーと AutoControllerModule を使用すると、コントローラーが自動的に登録されます。
于 2009-08-05T04:53:57.733 に答える
2

カーネルを作成するときに指定するモジュールのリストにAutoControllerModuleを追加する必要があります。以下に示します。

protected override IKernel CreateKernel()
{
    IKernel kernel = new StandardKernel(
                         new BaseModule(), 
                         new AutoControllerModule(Assembly.GetExecutingAssembly())
                     );
    return (kernel);
}

AutoControllerModuleは、Ninject 1.x の MVC サポートの一部です。MVC コントローラー クラスのコンストラクターに提供するアセンブリをスキャンし、それらを自動バインドします。コードでは、リポジトリを適切にバインドしていますが、Ninject はコントローラーのアクティブ化を担当していません。リポジトリをHomeControllerクラスのインスタンスに注入するには、Ninject がコントローラーの作成とアクティブ化を担当する必要があります。AutoControllerModuleがなければ、MVC が引き続きコントローラーの作成を担当します。したがって、Ninject はメンバーを注入する機会を得ることはありません。Ninject がコントローラーの作成とアクティブ化を担当すると、期待どおりに注入が行われます。

AutoControllerModuleは、すべてのコントローラーを検索し、次のようなコードを生成するものと考えてください (HomeController は例として使用されています) 。

Bind<HomeController>.ToSelf();
于 2009-08-05T15:46:22.820 に答える