Ninject UserManager and UserStore

2019-02-18 13:18发布

问题:

What is the most elegant way to inject UserManager and UserStore into a controller using ninject? For example, the context can be injected like this:

 kernel.Bind<EmployeeContext>().ToSelf().InRequestScope();

    public class EmployeeController : Controller
    {
    private EmployeeContext _context;

    public EmployeeController(EmployeeContext context)
    {
        _context = context;
    }

Can ninject inject UserManager and UserStore with a one line of code into a controller?! If not, what is the easiest way? I don't want to use this:

 var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));

Thank you in advance.

回答1:

Sure thing, you only need to make sure there's bindings for all dependencies (ApplicationDbContext, UserManager<T> and UserStore<T>). Binding open generics is done like this:

kernel.Bind(typeof(UserStore<>)).ToSelf().InRequestScope(); // scope as necessary.

if it would have an interface, you'd bind it like this:

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

So, with these bindings you should be good to go:

kernel.Bind<ApplicationDbContext>().ToSelf().InRequestScope();
kernel.Bind(typeof(UserManager<>)).ToSelf(); // add scoping as necessary
kernel.Bind(typeof(UserStore<>)).ToSelf(); // add scoping as necessary


回答2:

Spent 8 hours trying to figure this one out, and I think I have it. The one difference that might need to be modified in other implementations is the SharedContext. My code has a SharedContext that inherits from DBContext.

kernel.Bind(typeof(DbContext)).To(typeof(SharedContext)).InRequestScope();
kernel.Bind(typeof(IUserStore<ApplicationUser>)).To(typeof(UserStore<ApplicationUser>)).InRequestScope();
kernel.Bind(typeof(UserManager<ApplicationUser>)).ToSelf().InRequestScope(); 

I Also made changes to the AccountController.

//public AccountController()
        //    : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new SharedContext())))
        //{

        //}

        public AccountController(UserManager<ApplicationUser> userManager, UserStore<ApplicationUser> userStore)
        {
            _userStore = userStore;
            _userManager = userManager;
        }

        private UserManager<ApplicationUser> _userManager { get; set; }
        private UserStore<ApplicationUser> _userStore { get; set; }

Hope this saves someone else some time.