【发布时间】:2012-07-13 12:09:27
【问题描述】:
因此,经过一番折腾,我终于将 Ninject 连接起来并在我的 MVC4 应用程序中编译。我遇到的问题是 IDependencyScope 接口不再存在,并且 System.Web.Http.Dependencies 命名空间已被取消。
所以,我现在的问题是我已经连接了所有东西,并且在运行我得到的应用程序时:
Sequence contains no elements
[InvalidOperationException: Sequence contains no elements]
System.Linq.Enumerable.Single(IEnumerable`1 source) +379
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:31
Ninject.Web.Common.Bootstrapper.Initialize(Func`1 createKernelCallback) in c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs:53
Ninject.Web.Common.NinjectHttpApplication.Application_Start() in c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\NinjectHttpApplication.cs:81
我无法追踪甚至无法理解它的来源。
我在 Global.asax.cs 中的标准 Ninject 方法如下所示:
protected override IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
kernel.Bind<IRenderHelper>().To<RenderHelper>();
GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new NinjectDependencyResolver(kernel));
return kernel;
}
protected override void OnApplicationStarted()
{
base.OnApplicationStarted();
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
BundleTable.Bundles.RegisterTemplateBundles();
}
还有我的自定义解析器:
public class NinjectDependencyResolver : IDependencyResolver
{
private readonly IKernel _kernel;
public NinjectDependencyResolver(IKernel kernel)
{
_kernel = kernel;
}
public object GetService(Type serviceType)
{
return _kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return _kernel.GetAll(serviceType);
}
catch (Exception)
{
return new List<object>();
}
}
public void Dispose()
{
// When BeginScope returns 'this', the Dispose method must be a no-op.
}
}
这里的任何见解将不胜感激。我已经花了太多时间试图将任何 DI 框架连接到在 .NET 4.5 上运行的最新 MVC4 RC 中,现在已经达到了我对根本不工作的东西的容忍度..
编辑#1 在 github 中深入研究 ExtensionsForIEnumerableOfT.cs 并没有多大帮助:
如果我自己写的话,我可能会开始理解这一点,但 Bootstrapper.cs 也没有太大帮助。
https://github.com/ninject/Ninject.Web.Common/blob/master/src/Ninject.Web.Common/Bootstrapper.cs
希望这些细节能让任何可能对 Ninject 有更多经验的人更轻松。
Edit #2遇到的错误具体是在NinjectMvcHttpApplicationPlugin.cs中:
违规行是:
ModelValidatorProviders.Providers.Remove(ModelValidatorProviders.Providers.OfType<DataAnnotationsModelValidatorProvider>().Single());
生活在以下方法中:
public void Start()
{
ModelValidatorProviders.Providers.Remove(ModelValidatorProviders.Providers.OfType<DataAnnotationsModelValidatorProvider>().Single());
DependencyResolver.SetResolver(this.CreateDependencyResolver());
RemoveDefaultAttributeFilterProvider();
}
ModelValidatorProviders 集合包含 2 个元素: {System.Web.Mvc.DataErrorInfoModelValidatorProvider} {System.Web.Mvc.ClientDataTypeModelValidatorProvider}
它正在尝试删除单个实例:
System.Web.Mvc.DataAnnotationsModelValidatorProvider
这显然没有加载到 ModelValidationProviders.Providers 集合中。这里有什么想法吗?
解决上述例外并进入下一个
为了解决 ModelValidatorProviders 中的问题,我必须手动添加它所期望的对象。所以现在我的 CreateKernel 方法看起来像:
protected override IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
kernel.Bind<IRenderHelper>().To<RenderHelper>();
kernel.Unbind<IDocumentViewerAdapter>();
GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new NinjectDependencyResolver(kernel));
ModelValidatorProviders.Providers.Add(new DataAnnotationsModelValidatorProvider());
FilterProviders.Providers.Add(new FilterAttributeFilterProvider());
return kernel;
}
现在它运行并进入了 Ninject 的实际内容,但仍然存在一个问题,又一个毫无意义的问题:
Exception Details: Ninject.ActivationException: Error activating IntPtr
No matching bindings are available, and the type is not self-bindable.
Activation path:
3) Injection of dependency IntPtr into parameter method of constructor of type Func{IKernel}
2) Injection of dependency Func{IKernel} into parameter lazyKernel of constructor of type HttpApplicationInitializationHttpModule
1) Request for IHttpModule
Suggestions:
1) Ensure that you have defined a binding for IntPtr.
2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.
3) Ensure you have not accidentally created more than one kernel.
4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.
5) If you are using automatic module loading, ensure the search path and filters are correct.
【问题讨论】:
-
任何急于寻找谷歌搜索答案的人可能不会得到它,但欢迎您尝试。我已经阅读了通过我自己在 google 上的前 10 页搜索可以找到的每一篇文章。目前还没有任何关于我可能做错了什么的见解。
-
我已经在我的 MVC4 应用程序中安装了 Ninject.MVC3 nuget 包,并且 DI 开箱即用。可以尝试一下吗?
-
这里也一样,MVC4 和 Ninject.MVC3 包是一种享受...虽然在 .NET 4 上,而不是 4.5...
-
我认为这就是问题所在…… System.Web.Http 命名空间中发生了一些变化,并且删除了 Dependencies 命名空间。 IDependencyResolver 现在位于 System.Web.Http.Services 中,不在 Dependencies 下。
-
嗨,让标题简短地显示问题是什么总是有帮助的。
标签: c# ninject asp.net-mvc-4