如何在ASP.NET MVC Web应用程序中使用Ninject?

26

我创建了一个新的MVC Web应用程序,并引用了Ninject.dll、Ninject.Web.Common.dll和Ninject.Web.MVC.dll。

Global.asax.cs:

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
                });
        }

        protected override IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            kernel.Load(Assembly.GetExecutingAssembly());
            return kernel;
        }

        protected override void OnApplicationStarted()
        {
            base.OnApplicationStarted();

            AreaRegistration.RegisterAllAreas();
            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
        }
    }

App_start\NinjectWebCommon:

->

App_start\NinjectWebCommon:

public static class NinjectWebCommon 
    {
        private static readonly Bootstrapper bootstrapper = new Bootstrapper();

        /// <summary>
        /// Starts the application
        /// </summary>
        public static void Start() 
        {
            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
            bootstrapper.Initialize(CreateKernel);
        }

        /// <summary>
        /// Stops the application.
        /// </summary>
        public static void Stop()
        {
            bootstrapper.ShutDown();
        }

        /// <summary>
        /// Creates the kernel that will manage your application.
        /// </summary>
        /// <returns>The created kernel.</returns>
        private static IKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
            kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

            RegisterServices(kernel);
            return kernel;
        }

        /// <summary>
        /// Load your modules or register your services here!
        /// </summary>
        /// <param name="kernel">The kernel.</param>
        private static void RegisterServices(IKernel kernel)
        {
        }        
    }
我遇到了错误 "序列不包含任何元素",我做错了什么?
错误详细信息:
Description: An unhandled exception occurred during the execution of the current web request. Examine the stack trace for more information about this error and where it originated in the code.

Exception Details: System.InvalidOperationException: Sequence contains no elements

Source Error:
  Unhandled exception occurred during execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.


Stack Trace:

[InvalidOperationException: Последовательность не содержит элементов]
   System.Linq.Enumerable.Single(IEnumerable`1 source) +320
   Ninject.Web.Mvc.NinjectMvcHttpApplicationPlugin.Start() in c:\Projects\Ninject\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectMvcHttpApplicationPlugin.cs:53
   Ninject.Web.Common.Bootstrapper.<Initialize>b__0(INinjectHttpApplicationPlugin c) in c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs:52
   Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map(IEnumerable`1 series, Action`1 action) in c:\Projects\Ninject\ninject\src\Ninject\Infrastructure\Language\ExtensionsForIEnumerableOfT.cs:32
   Ninject.Web.Common.Bootstrapper.Initialize(Func`1 createKernelCallback) in c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs:52
   Ninject.Web.Common.NinjectHttpApplication.Application_Start() in c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\NinjectHttpApplication.cs:80

你能添加完整的堆栈跟踪吗? - Remo Gloor
看起来第53行试图从MVC中移除DataAnnotationsModelValidatorProvider。你是否使用了正确的MVC版本/在某种程度上已经配置它? - Rup
3个回答

40

需要明确的是,如果您使用NuGet添加了“Ninject.Mvc3”包(我使用的版本是3.0.0.6),那么不需要对global.asax.cs进行任何修改。 NuGet包通过在MVC 4项目的App_Start文件夹中创建NinjectWebCommon类来为您完成操作。

我之所以这样说,是因为我似乎遵循了与原始发布者类似的教程(我遵循了The Code Project上的一篇文章,称为“Dependency Injection in asp.net mvc4 and webapi using Ninject'),并且和原始发布者一样遇到了同样的问题。该Code Project文章没有明确指出您应该要么使用NuGet(并且不要触摸global.asax.cs要么手动添加Ninject引用(并修改global.asax.cs)。


24

您正在从NinjectHttpApplication派生,并同时使用App_Start。选择其中一个!阅读Ninject.MVC3的文档以获取更多信息。


啊,好的 - 所以他看到关于删除DataAnnotationsModelValidatorProvider的错误的原因是他第二次初始化Ninject,而第一次初始化已经将其删除了?我想这是一个有用的提示,但它应该更优雅地失败。 - Rup
5
@Remo Gloor - 我必须说,即使有文档,这两种不同的方法对于初学者来说仍然非常令人困惑。文档确实基本上说“它们完全相同”,但是观察代码,Nuget方式具有一个空的“RegisterServices”方法,而NinjectHttpApplication方式具有“kernal.Load(Assembly.GetExecutingAssemby)”。 这些并不相同,在文档页面上提供更多指导将非常受欢迎。这是人们可能会在Ninject上找到的第一页之一,对于初学者来说,更多细节将是很好的补充。 - Simon_Weaver
@Simon_Weaver 已经添加了 RegisterServices 方法到 NinjectHttpApplication 中,以便拥有相同的注册代码实现。现在它真的是一样的了。如果您需要更多信息,请添加 TODO 来指出您认为缺少的内容,或者如果您知道答案,可以自己添加。 - Remo Gloor
2
我想看一个访问通过NinjectWebCommon类创建的内核的例子。我有一个自定义控制器工厂,并且在尝试找出可以从哪里访问内核实例时遇到了问题。 - Stephen Price

7

请确保您没有引用同样使用了 NinjectMVC3 App_Start 的工程。 在移除这样的引用之后,我的项目开始工作了。同时,请确认所有命名空间都匹配且正确。


那正是我的问题。谢谢你的提示! - code5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接