Dependency injecting UserStore in OWIN startup using Ninject OWIN middleware

后端 未结 2 1628
猫巷女王i
猫巷女王i 2021-01-30 13:31

I am having problems creating a custom UserStore using dependency injection when creating an ApplicationUserManager using the OWIN request pipeline.

Background

2条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-01-30 13:52

    For info:

    It is possible to register the kernel as a singleton so that the same kernel can be used by the ninject middleware and also registered within the owin context.

        public static StandardKernel CreateKernel()
        {
            if (_kernel == null)
            {
                _kernel = new StandardKernel();
                _kernel.Bind().To();
    
                _kernel.Load(Assembly.GetExecutingAssembly(), Assembly.Load("Super.CompositionRoot"));
            }
            return _kernel;
        }
    

    The callback function app.CreatePerOwinContext(ApplicationUserManager.Create), will call the ApplicationUserManager.Create rather than register it to be called at a later point during the setup. Therefore, the CreateKernel function needs to be registered before the ApplicationUserManager's Create callback or you will get a null reference exception if you try to get the kernel from the owin context within that method.

        public void ConfigureAuth(IAppBuilder app)
        {
            app.CreatePerOwinContext(CreateKernel);
            app.UseNinjectMiddleware(CreateKernel);
            app.CreatePerOwinContext(ApplicationUserManager.Create);
         }
    

    This will allow you to access the kernel to create a custom UserStore within the ApplicationUserManager's Create callback:

        public static ApplicationUserManager Create(IdentityFactoryOptions options, IOwinContext context)
        {
            var kernel = context.Get();
            var userStore = kernel.Get>();
            var manager = new ApplicationUserManager(userStore);
            //...
        }
    

    I know that in general dependency injection should be favoured over service location, but in this context I couldn't see a way around it - unless anybody has any better suggestions?

    This will allow you to use Ninject to implement the unit of work patter leveraging Ninject's InRequestScope().OnDeactivation functionality. I'm aware that the UserManager class has a per request lifetime, but didn't know the most the most appropriate way to commit any outstanding transactions on request finish.

提交回复
热议问题