user4266661
user4266661

Reputation:

MVC/nInject: Implementing My Own ApplicationUserManager

I'm using nInject in an MVC4 app. I would like to implement my own version of ApplicationUserManager because the scaffolded one creates a separate instance of my database context (I use nInject to inject a request scope database context into my controllers). Having a separate database context in ApplicationUserManager is causing some odd problems when manipulating the user credentials.

But I'm running into a problem creating the nInject bindings:

private static void RegisterServices(IKernel kernel)
{
    kernel.Bind<CampaignDbContext>().ToSelf().InRequestScope();
    kernel.Bind<ApplicationUserManager>().ToSelf().InRequestScope();
    kernel.Bind<ApplicationSignInManager>().ToSelf().InRequestScope();
}        

The first one works fine, presumably because CampaignDbContext has a parameterless constructor.

But the second and third ones fail. ApplicationUserManager's constructor is defined as:

public ApplicationUserManager( CampaignDbContext context )
    : base( new UserStore<CampaignDbUser>( context ) )
{
    // Configure validation logic for usernames
    UserValidator = new UserValidator<CampaignDbUser>(this)
    {
        AllowOnlyAlphanumericUserNames = true,
        RequireUniqueEmail = true
    };
    // etc

I thought that because CampaignDbContext is itself self-bound that its instance would be passed in to ApplicationUserManager's constructor. But that doesn't seem to be happening based on the error message I'm getting.

How do I configure the nInject binding?

Upvotes: 1

Views: 953

Answers (1)

Chris Pratt
Chris Pratt

Reputation: 239260

ApplicationUserManager should inherit from UserManager<TUser>. The constructor for UserManager<TUser> takes UserStore<TUser>, and finally the constructor for UserStore<TUser> takes a DbContext.

Instead of trying to pass in the context to ApplicationUserManager which should have a dependency on it in the first place, just tell Ninject how to implement IUserStore<TUser>:

kernel.Bind<DbContext>().To<CampaignDbContext>().InRequestScope();
kernel.Bind(typeof(IUserStore<>)).To(typeof(UserStore<>)).InRequestScope();

Then, you can just inject ApplicationUserManager where it needs to go and Ninject will automatically fill it with a UserManager<TUser> instance that is initialized with your CampaignDbContext.

Upvotes: 4

Related Questions