c# - MVC5 和 Ninject 的依赖注入(inject)失败

标签 c# dependency-injection asp.net-mvc-5 ninject.web.mvc

我试图在 Controller 中注入(inject)几个类,但失败了。

这就是我所做的:

  1. 添加了 Ninject.Web.WebApi.WebHostWebActivatorEx NuGet 包
  2. App_Start下创建了以下类:

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();
        }
    }
}
  • 创建了我的类(class):
  • 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
        }
    }
    
  • 创建了一个 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 不起作用。

    最佳答案

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

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

    这样,只要在代码中需要 IMyContext 依赖项,您就可以告诉 DI 容器实例化 MyContext

    关于c# - MVC5 和 Ninject 的依赖注入(inject)失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47724068/

    相关文章:

    c# - 接口(interface)或类的依赖注入(inject)

    c# - 默认参数值到另一个参数

    c# - 在运行时加载 2 个版本的程序集

    c# - 如何在 Entity Framework 中将一个类类型的集合转换为另一种类类型集合

    asp.net-mvc-5 - 使用 ASP.NET Identity 执行 CRUD 的最佳方法是什么?

    asp.net-mvc - ASP.Net MVC 5 + SignalR + Ninject

    c# - HTTP post 上的 MVC 模型子对象为 null

    c# - 错误 : Invoke or BeginInvoke cannot be called on a control until the window handle has been created

    c# - 编译时/构建后依赖注入(inject) IoC?

    c# - 我应该将 Unity 容器传递给我的依赖项吗?