簡體   English   中英

依賴注入失敗,MVC5和Ninject

[英]Dependency Injection fails with MVC5 and Ninject

我試圖在控制器中注入幾個類,但我失敗了。

這就是我所做的:

  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();
        }
    }
}
  1. 創建了我的課程:

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

但是,當我運行應用程序時,我仍然得到關於缺少無參數構造函數的臭名昭着的錯誤。 這告訴我DI不起作用。

我相信你在RegisterServices中的注冊調用是錯誤的 - 你不能綁定一個接口.ToSelf() - 你需要將接口綁定到實現它的具體類 - 如下所示:

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

有了這個,你告訴DI容器在你的代碼中只要你想要一個IMyContext依賴項就實例化一個MyContext

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM