如何注入RoleManager

How to inject RoleManager

我需要在 ASP.NET MVC 5 应用程序中使用 Ninject 将 RoleManager 注入控制器。我是 DI 和 Ninject 的新手,所以我不完全了解 Ninject 的作用。我使用 Ninject 3.3.4,来自 Identity 2.0 和 EF6.2 的标准 RoleManager。我的绑定如下:

public class NinjectRegistrations : NinjectModule
{
    public override void Load()
    {
        Bind<HeroesContext>().ToSelf();
        Bind<IRepository<Hero>>().To<HeroRepository>();
        Bind<IRepository<Ability>>().To<AbilityRepository>();
        Bind<IUserStore<ApplicationUser>>().To<UserStore<ApplicationUser>>().WithConstructorArgument("context", new HeroesContext());
        Bind<UserManager<ApplicationUser>>().ToSelf();
        Bind<HttpContextBase>().ToMethod(ctx => new HttpContextWrapper(HttpContext.Current)).InTransientScope();
        Bind<ApplicationSignInManager>().ToMethod(context =>
        {
            var cbase = new HttpContextWrapper(HttpContext.Current);
            return cbase.GetOwinContext().Get<ApplicationSignInManager>();
        });
        Bind<ApplicationUserManager>().ToSelf();
        Bind<IRoleStore<IdentityRole, string>>().To<RoleStore<IdentityRole, string, IdentityUserRole>>();
        Bind<RoleManager<IdentityRole, string>>().ToSelf();
    }
}

在 RoleManager 之前,我已经成功地在 HomeController 中注入了两个存储库,它们工作正常。我还在 AdminController 中注入了 ApplicationUserManager,在 AccountController 中注入了 AccountController 和 ApplicationSignInManager,它们似乎也工作正常,因为我可以登录。当前的问题与 RoleManager 有关,起初根本没有任何效果。经过一番谷歌搜索后,我发现了 this question,这在一定程度上有所帮助。现在,当我尝试使用 AdminController 获取用户列表时,我得到了这个和基本建议:

Ninject.ActivationException: Error activating DbConnection

No matching bindings are available, and the type is not self-bindable.

Activation path:

5) Injection of dependency DbConnection into parameter existingConnection of constructor of type DbContext

4) Injection of dependency DbContext into parameter context of constructor of type RoleStore{IdentityRole, string, IdentityUserRole}

3) Injection of dependency IRoleStore{IdentityRole, string} into parameter store of constructor of type RoleManager{IdentityRole, string}

2) Injection of dependency RoleManager{IdentityRole, string} into parameter roleManager of constructor of type AdminController

1) Request for AdminController

我试图找到解决方案,但没有找到任何有用的东西。您可以在下面找到 AdminController 的构造函数 Application_Start() 和上下文(我不确定是否需要)的代码。请帮忙,我的招聘取决于此。

public class AdminController : Controller
{
    private readonly ApplicationUserManager _userManager;
    private readonly RoleManager<IdentityRole> _roleManager;

    public AdminController(ApplicationUserManager userManager, RoleManager<IdentityRole> roleManager)
    {
        _userManager = userManager;
        _roleManager = roleManager;
    }
}

protected void Application_Start()
{
    Database.SetInitializer<HeroesContext>(new DbInitializer());

    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    var registrations = new NinjectRegistrations();
    var kernel = new StandardKernel(registrations);
    kernel.Unbind<ModelValidatorProvider>();
    DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
}

public class HeroesContext : IdentityDbContext<ApplicationUser>
{
    public DbSet<Hero> Heroes { get; set; }
    public DbSet<Ability> Abilities { get; set; }

    public HeroesContext() : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    public static HeroesContext Create()
    {
        return new HeroesContext();
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<Hero>().HasMany(n => n.Abilities)
                                   .WithRequired(n => n.Hero)
                                   .HasForeignKey(n => n.HeroId);
    }
}

我猜想您的 RoleStore class 需要 DbContext 类型的依赖项。由于您对 DbContext 没有任何绑定,Ninject 退回到隐式自绑定。这意味着它试图通过构造函数创建 DbContext

public DbContext(DbConnection existingConnection, bool contextOwnsConnection)

但在此之前它无法创建 DbConnection,如消息中所述。

解决方案是:

  • 更改您的绑定:Bind<DbContext>().To<HeroesContext>();

  • 或将RoleStore中的依赖类型更改为HeroesContext