MVC5和Ninject依赖注入失败 [英] Dependency Injection fails with MVC5 and Ninject

查看:96
本文介绍了MVC5和Ninject依赖注入失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在控制器中注入几个类,但是失败了.

I'm trying to inject a couple of classes in a controller, but I'm failing.

这就是我所做的:

  1. 添加了Ninject.Web.WebApi.WebHostWebActivatorEx NuGet软件包
  2. App_Start下创建了以下类:
  1. Added Ninject.Web.WebApi.WebHost and WebActivatorEx NuGet packages
  2. Created the following class under App_Start:

NinjectWebCommon.cs

NinjectWebCommon.cs

using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
using Ninject.Web.Common.WebHost;
using MyProject;
using MyProject.Models;
using MyProject.Classes;
using System;
using System.Web;

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(NinjectWebCommon), "Stop")]

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

        public static void Start()
        {
            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
            bootstrapper.Initialize(CreateKernel);
        }

        public static void Stop()
        {
            bootstrapper.ShutDown();
        }

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

        private static void RegisterServices(IKernel kernel)
        {
            kernel.Bind<IMyContext>().ToSelf().InRequestScope();
            kernel.Bind<IErp>().ToSelf().InRequestScope();
        }
    }
}

  1. 创建了我的课程:

MyContext.cs:

MyContext.cs:

using MyProject.Models;
using System;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Threading.Tasks;

namespace MyProject.Models
{
    public interface IMyContext : IDisposable
    {
        DbSet<Operator> Operators { get; set; }
        Task<int> SaveChangesAsync();
    }

    public class MyContext : DbContext, IMyContext
    {
        public MyContext () : base("MyContext ") { }
        public DbSet<Operator> Operators { get; set; }
        public async override Task<int> SaveChangesAsync()
        {
            return await SaveChangesAsync(CancellationToken.None);
        }
    }
}

Erp.cs

public interface IErp
{
    Task ImportListAsync();
}

public class Erp : IErp
{
    private readonly IMyContext _context;
    public Erp(IMyContext context)
    {
        _context = context;
    }

    public async Task ImportListAsync()
    {
        // do something
    }
}

  1. 创建一个控制器

  1. Created a Controller

using MyProject.Classes;
using MyProject.Models;
using System.Data.Entity;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace MyProject.Controllers
{
    public class OperatorsController : Controller
    {
        private readonly IMyContext _context;
        private readonly IErp _erp;

        public OperatorsController(IMyContext context, Erp Ierp)
        {
            _context = context;
            _erp = erp;
        }

        // GET: Operators
        public async Task<ActionResult> Index()
        {
            return View(await _context.Operators.ToListAsync());
        }

        // GET: Operators/Import
        public async Task<ActionResult> Import()
        {
            await _erp.ImportListAsync();
            return View("Index", await _context.Operators.ToListAsync());
        }
    }
}

但是当我运行应用程序时,我仍然收到关于缺少无参数构造函数的声名狼藉的错误.这对我说DI无效.

But when I run the application I still get the infamous error about the missing of parameterless constructor. This says to me that DI is not working.

推荐答案

我相信您在RegisterServices中的注册调用是错误的-无法绑定接口.ToSelf()-您需要将接口绑定到混凝土类来实现它-像这样:

I believe your registration calls in RegisterServices are wrong - you cannot bind an interface .ToSelf() - you need to bind the interface to the concrete class that implements it - something like this:

private static void RegisterServices(IKernel kernel)
{
    kernel.Bind<IMyContext>().To<MyContext>().InRequestScope();
    kernel.Bind<IErp>().To<Erp>().InRequestScope();
}

有了这个,您告诉DI容器在代码中每当需要IMyContext依赖项时就实例化MyContext

With this, you tell the DI container to instantiate an MyContext class whenever in your code you're expecting an IMyContext dependency

这篇关于MVC5和Ninject依赖注入失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆