ASP.NET MVC4中的Ninject

Vul*_*ary 20 c# ninject asp.net-mvc-4

所以经过多次搞砸后,我终于将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
Run Code Online (Sandbox Code Playgroud)

我无法追踪甚至开始了解它的来源.

我在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();
        }
Run Code Online (Sandbox Code Playgroud)

我的定制解析器:

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.
     }
}
Run Code Online (Sandbox Code Playgroud)

任何见解将不胜感激.我已经花了太多时间试图将任何DI框架连接到运行在.NET 4.5上的最新MVC4 RC,并且现在刚刚达到我对容易处理的事情的容忍度.

编辑#1 在github中挖掘ExtensionsForIEnumerableOfT.cs的进一步研究并没有多大帮助:

https://github.com/ninject/ninject/blob/master/src/Ninject/Infrastructure/Language/ExtensionsForIEnumerableOfT.cs

可能如果我自己写了它,我会开始理解这一点,但Bootstrapper.cs也没有太大帮助.

https://github.com/ninject/Ninject.Web.Common/blob/master/src/Ninject.Web.Common/Bootstrapper.cs

希望这些细节可以让任何对Ninject有更多经验的人更容易.

编辑#2 遇到的错误特别是在NinjectMvcHttpApplicationPlugin.cs中:

违规行是:

ModelValidatorProviders.Providers.Remove(ModelValidatorProviders.Providers.OfType<DataAnnotationsModelValidatorProvider>().Single());
Run Code Online (Sandbox Code Playgroud)

其中存在以下方法:

public void Start()
{
    ModelValidatorProviders.Providers.Remove(ModelValidatorProviders.Providers.OfType<DataAnnotationsModelValidatorProvider>().Single());
    DependencyResolver.SetResolver(this.CreateDependencyResolver());
    RemoveDefaultAttributeFilterProvider();
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

现在它运行并进入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.
Run Code Online (Sandbox Code Playgroud)

Vul*_*ary 18

好吧,我把头撞到墙上太久了,我弄清楚发生了什么事.在.NET 4.5上运行的MVC4的默认项目类型引用了System.Web.Http的原始RC版本而不是更新版本.

命名空间丢失,对象不存在,生活不好.

解决步骤:

  1. 删除MVC4项目中对System.Web.Http的引用
  2. 添加引用 - > System.Web.Http
  3. 删除您放入的所有工作,以使旧的垃圾版本的System.Web.Http工作
  4. 在Ninject中重新应用标准流程进行连线.

    但是,错误:

    异常详细信息:Ninject.ActivationException:错误激活的IntPtr没有匹配的绑定是可用的,并且该类型不是自可绑定.激活路径:3)的依赖性的IntPtr注射入型函数功能{的iKernel} 2)依赖性Func键{的iKernel}的注射液的构造的参数方法成型HttpApplicationInitializationHttpModule 1)请求的IHttpModule的构造的参数lazyKernel

    建议:1)确保已为IntPtr定义了绑定.2)如果在模块中定义了绑定,请确保已将模块加载到内核中.3)确保您没有意外创建多个内核.4)如果使用构造函数参数,请确保参数名称与构造函数参数名称匹配.5)如果使用自动模块加载,请确保搜索路径和过滤器正确无误.

更新这是通过将MVC从MVC4 Beta更新为MVC4 RC来解决的.


anA*_*ent 5

查看Pro ASP.NET MVC 3书.我昨晚刚将这段代码从MVC3移植到MVC4并正常工作.确切地说是第322页.

我没看到的是您将接口映射到具体项目的位置.

Bind<ISomething>().To<Something>();
Run Code Online (Sandbox Code Playgroud)

添加另一个构造函数并添加调用映射的方法;

public NinjectDependencyResolver() {
    _kernal = new StandardKernel();
    RegisterServices(_kernel);
}

public static void RegisterServices(IKernel kernel) {
    kernel.Bind<ISomething>().To<Something>();
}
Run Code Online (Sandbox Code Playgroud)

这是解析器可能/应该是什么样子;

   public class NinjectDependencyResolver : IDependencyResolver {
    private IKernal _kernel;

    public NinjectDependencyResolver(){
        _kernal = StandardKernal();
        AddBindings();
    }

    public NinjectDependencyResolver(IKernel kernel)
    {
        _kernel = kernel;
    }

    public object GetService(Type serviceType)
     {
         return _kernel.TryGet(serviceType);
     }

     public IEnumerable<object> GetServices(Type serviceType)
     {
        return _kernal.GetAll(serviceType);
     }

    public IBindingToSyntax<T> Bind<T>() {
      return _kernal.Bind<T>();
    }

     public static void RegisterServices(IKernel kernel){
      //Add your bindings here. 
      //This is static as you can use it for WebApi by passing it the IKernel
     }
}
Run Code Online (Sandbox Code Playgroud)

Global.Asx -

的Application_Start()

方法

DependencyResolver.SetResolver(new NinjectDependencyResolver());
Run Code Online (Sandbox Code Playgroud)

而已.


更新时间:11/14/2012

另外,如果您正在使用MVC WebAPI,则需要使用nuget中的WebApiContrib.IoC.Ninject.另外,请查看样本asp.net.com中的"联系人管理器" .这有助于清理Ninject的实现