Ninject入门

时间:2011-02-17 16:28:21

标签: c# asp.net-mvc-3 ninject-2

我在dimecasts.net上观看了Ninject的前两个初学者教程。现在,我想在ASP.NET MVC 3中使用Ninject 2.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>

修改 11/20/2013

请注意,Ninject已发布2.0版本。他们的site很好地概述了这些变化。注意StandardModule现在是NinjectModule,而命名空间Ninject.Core已不复存在。我只能用Ninject替换它。

3 个答案:

答案 0 :(得分:15)

您的控制器类存在问题,具有依赖关系的构造函数是私有。您的控制器应如下所示:

public class HomeController : Controller
{
    private readonly IMilestoneService _service;

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

}

甚至不包含公共无参数构造函数,它甚至不是有效的,您的类需要该依赖项才能运行。

实际上,我还在构造函数中对该依赖项插入了一个空检查,以确保我的类在构造时有效:

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中看到它。

答案 1 :(得分:6)

在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
}

答案 2 :(得分:3)

我相信如果Ninject无法绑定该接口,则会出现绑定错误。这让我觉得Ninject 实例化你的控制器。

您是否已加入Ninject.Web.Mvc