QuarK
QuarK

Reputation: 1302

How to inject RoleManager

I need to inject RoleManager into Controller using Ninject in ASP.NET MVC 5 application. I am totally new in DI and Ninject, so I am not fully understand what Ninject do. I use Ninject 3.3.4, standard RoleManager from Identity 2.0 and EF6.2. My bindings are below:

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

Before RoleManager I have successfully inject two repositories in HomeController, their work fine. Also I injected ApplicationUserManager in AdminController and AccountController and ApplicationSignInManager in AccountController, it seems their work fine too because I can log in. Current problem is connected with RoleManager, at first nothing worked at all. After some googling I found this question, it helped partly. Now when I try do get list of users using AdminController I get this and basic recommendations:

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

I tried to find solution, but found nothing useful. Below you can find code of AdminController's constructor, Application_Start() and context (I'm not sure it is needed). Please help, my hiring depends on this.

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

Upvotes: 1

Views: 2157

Answers (1)

Jan Muncinsky
Jan Muncinsky

Reputation: 4408

I guess that your RoleStore class is expecting dependency of type DbContext. And since you don't have any binding to DbContext, Ninject falls back to implicit self-binding. That means it tries to create DbContext trough the constructor:

public DbContext(DbConnection existingConnection, bool contextOwnsConnection)

but before that it can't create DbConnection as explained in the message.

Solution is:

  • change your binding: Bind<DbContext>().To<HeroesContext>();

  • or change type of the dependency in RoleStore toHeroesContext

Upvotes: 1

Related Questions