依赖注入失败,MVC5和Ninject

时间:2017-12-09 00:32:14

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

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

这就是我所做的:

  1. 添加了Ninject.Web.WebApi.WebHostWebActivatorEx NuGet包
  2. App_Start下创建了以下类:
  3. 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. 创建了我的课程:
    2. 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. 创建了一个控制器

        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());
                }
            }
        }
        
      2. 但是当我运行应用程序时,我仍然得到关于缺少无参数构造函数的臭名昭着的错误。这告诉我DI没有用。

1 个答案:

答案 0 :(得分:3)

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

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

有了这个,你告诉DI容器在代码中每当你期望MyContext依赖

时实例化IMyContext