7

dimecasts.netでNinjectの最初の2つの初心者向けチュートリアルを見ました。ここで、ASP.NETMVC3でNinject2.2を使用したいと思います。モデルをモックアウトしたビューが必要です。サービスを呼び出すときに、オブジェクトのインスタンスに設定されていないオブジェクト参照を取得します。

    public class HomeController : Controller
    {
        private readonly IMilestoneService _service;

        public HomeController()
        {
        }

        HomeController(IMilestoneService service)
        {
            _service = service;
        }

        public ActionResult Index()
        {
            ViewBag.Message = "Change Request System";

            return View();
        }

        public ActionResult About()
        {
            return View();
        }

        #region Partial views
        public ActionResult Milestone()
        {
            var result = _service.GetMileStones();//OBJECT REF ERROR
            return View(result);
        }
        #endregion
    }

//####GLOBAL.ASAX
//By using the NinjectHttpApplication, it automatically takes care of controllers, starting up mvc, etc.
//Ninject.Web.Mvc
public class MvcApplication : NinjectHttpApplication
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }

    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 = UrlParameter.Optional } // Parameter defaults
        );

    }

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);

        //StartNinject();
    }

    #region Inversion of Control

    protected override IKernel CreateKernel()
    {
        return Container;
    }

    static IKernel _container;
    public static IKernel Container
    {
        get
        {
            if (_container == null)
            {
                _container = new StandardKernel(new SiteModule());
            }
            return _container;
        }
    }

    internal class SiteModule : NinjectModule
    {
        public override void Load()
        {
            //Set up ninject bindings here.
            Bind<IMilestoneService>().To<MileStoneService>();
        }
    }
    #endregion
}

私はRazorを使用しています、彼は画期的な部分的なビューです

@foreach (var item in Model)
{
    <div>item.Name</div>
}

最後に、ホームビューインデックス

@{
    ViewBag.Title = "Home Page";
}

<h2>@ViewBag.Message</h2>
<p>
   @Html.Action("Milestone");
</p>

2013年11月20日編集

Ninjectはバージョン2.0をリリースしたことに注意してください。変更は彼らのサイトでうまく概説されています。注目すべきStandardModuleは現在NinjectModuleであり、名前空間Ninject.Coreはもう存在しません。に置き換えることができましたNinject

4

3 に答える 3

16

コントローラクラスに問題があります。依存関係のあるコンストラクタはprivateです。コントローラは次のようになります。

public class HomeController : Controller
{
    private readonly IMilestoneService _service;

    public HomeController(IMilestoneService service)
    {
        _service = service;
    }

}

パブリックパラメーターレスコンストラクターも含めないでください。有効ではありません。クラスが機能するには、その依存関係が必要です。

実際、クラスが構築時に有効であることを確認するために、コンストラクターにその依存関係に対するnullチェックも挿入します。

public class HomeController : Controller
{
    private readonly IMilestoneService _service;

    public HomeController(IMilestoneService service)
    {
        _service = service;
        Enforce.NotNull(() => _service); // lambda to auto-magically get variable name for exception
    }

}

MvcApplicationクラスにも問題がある可能性があります。

の代わりにprotected void Application_Start()、オーバーライドできる別の関数があります。protected override void OnApplicationStarted()

これは、ルーティングを設定するための呼び出しが行われるべき場所です。

public class MvcApplication : NinjectHttpApplication
{

    public override void Init()
    {
        base.Init();
        Mappers.Initialize();
    }

    protected override Ninject.IKernel CreateKernel()
    {
        return Ioc.Initialize();
    }

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

    public static void RegisterRoutes(RouteCollection routes) 
    {
        Routing.RegisterRoutes(routes);
        //RouteDebug.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);
    }
}

もちろん、あなたがすでにそれを呼んApplication_Startでいるなら、それも問題ありませんが、私はそれをOPで見ませんでした。

于 2011-02-17T17:17:48.483 に答える
7

global.asaxファイルでこれを試してください。

//By using the NinjectHttpApplication, it automatically takes care of controllers, starting up ninject, etc.
//Ninject.Web.Mvc
public class MvcApplication : NinjectHttpApplication
{
    //Your other stuff here. No need to call StartNinject().

    #region Inversion of Control

    protected override IKernel CreateKernel()
    {
        return Container;
    }

    static IKernel _container;
    public static IKernel Container
    {
        get
        {
            if (_container == null)
            {
                _container = new StandardKernel(new SiteModule());
            }
            return _container;
        }
    }

    internal class SiteModule : NinjectModule
    {
        public override void Load()
        {
            //Set up ninject bindings here.
            Bind<IMilestoneService>().To<MileStoneService>();
        }
    }
    #endregion
}
于 2011-02-17T16:44:02.587 に答える
4

Ninjectがそのインターフェースをバインドできなかった場合、バインドエラーが発生すると思います。これにより、Ninjectがコントローラーをインスタンス化していないように思われます。

Ninject.Web.Mvcを含めましたか?

于 2011-02-17T16:47:27.873 に答える