c# – 依赖注入在OWIN启动时使用Ninject OWIN中间件的UserStore

c# – 依赖注入在OWIN启动时使用Ninject OWIN中间件的UserStore


我在使用OWIN请求管道创建一个ApplicationUserManager时创建一个使用依赖注入的自定义UserStore有问题。

 

背景

我试图将我们的Web应用程序中的用户功能从使用SimpleMembership迁移到新的ASP.NET身份。当启动一个新的MVC 5项目时,单页应用程序的默认实现使用ASP.Identity,使用Entity Framework来实现UserStore功能。

在我的例子中,我们已经使用NHibernate作为ORM,并使用ninject来实现工作模式的单元,这样我们每个请求都有一个NHibernate会话,我想让ASP.Identity与我们现有的框架一起工作。

为此,我创建了一个自定义的UserStore,它可以通过注入相关的仓库/ nhibernate会话等创建。然后可以使用Ninject注入到Controller的构造函数中,而不是使用默认实现的GetOwinContext功能。

为了做到这一点,我已经注释掉了Startup的ConfigureAuth(IAppBuilder应用程序)方法中的以下行,它默认创建UserManager类:

 

// app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

相反,我使用在安装Ninject.Web.Common.Webhost nuget包时创建的NinjectWebCommon来创建相关的绑定。

这个实现对于一些UserManager操作很好,但是对于一些操作,例如ResetPasswordAsync,它失败,因为默认的ApplicationUserManager实现没有被调用,因此UserManager类中的UserTokenProvider从不设置:

 

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
    {
        var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<ApplicationUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };
        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = true,
            RequireDigit = true,
            RequireLowercase = true,
            RequireUppercase = true,
        };
        // Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
        // You can write your own provider and plug in here.
        manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider<ApplicationUser>
        {
            MessageFormat = "Your security code is: {0}"
        });
        manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider<ApplicationUser>
        {
            Subject = "Security Code",
            BodyFormat = "Your security code is: {0}"
        });
        manager.EmailService = new EmailService();
        manager.SmsService = new SmsService();
        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
        }
        return manager;
    }

因此,UserTokenProvider未设置。

问题

我想使用OWIN管道,因为Visual Studio的默认实现ApplicationUserManager类在其创建回调方法中注入IDataProtectionProvider。然而,我也想创建我的UserStore使用依赖注入,我不知道如何创建一个UserStore在这个方法使用依赖注入。

 

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        // WANT TO CREATE THE USER STORE USING NINJECT DEPENDENCY INJECTION HERE
        // var userStore = ...
        var manager = new ApplicationUserManager(userStore);
    }

我试图通过使用Ninject.Web.Common.OwinHost nuget包和在启动类中创建内核来绕过这个限制。

 

public void ConfigureAuth(IAppBuilder app)
    {
        // Setup

        app.UseNinjectMiddleware(CreateKernel);
    }

但是,Ninject.Web.Common.OwinHost不公开其内核,所以我无法使用服务定位模式注入的值到我的自定义UserStore在创建回调。

我也试图创建一个单例内核,并使用app.CreatePerOwinContext(CreateKernel)与相关委托注册,所以我可以稍后访问内核,但是当我调用context.Get()它只返回null。

如何使用CreatePerOwinContext注册一个回调函数来创建一个使用自定义UserStore的自定义UserManager,然后使用Ninject在创建回调中使用依赖注入创建自定义UserStore,这样我也可以访问Owin使用的IdentityFactoryOptions注入用户令牌提供程序?

 
信息:

 

可以将内核注册为单例,以便相同的内核可以由ninject中间件使用,并且也可以在owin上下文中注册。

 

public static StandardKernel CreateKernel()
    {
        if (_kernel == null)
        {
            _kernel = new StandardKernel();
            _kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

            _kernel.Load(Assembly.GetExecutingAssembly(), Assembly.Load("Super.CompositionRoot"));
        }
        return _kernel;
    }

回调函数app.CreatePerOwinContext(ApplicationUserManager.Create)将调用ApplicationUserManager.Create而不是注册它,以便在安装过程中稍后调用。因此,CreateKernel函数需要在ApplicationUserManager的Create回调之前注册,否则如果您尝试从该方法中的owin上下文中获取内核,您将获得一个空引用异常。

 

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

这将允许您访问内核以在ApplicationUserManager的Create回调中创建自定义UserStore:

 

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

我知道一般依赖注入应该优先于服务位置,但在这种情况下,我不能看到一个方法 – 除非有任何人有任何更好的建议吗?

这将允许您使用Ninject实现工作单元模式利用Ninject的InRequestScope()。OnDeactivation功能。我知道UserManager类有一个per request lifetime,但不知道最最适当的方式提交任何未完成的交易请求完成。

博文最后更新时间:


评论

  • Merziuz

    NEJV7n http://pills2sale.com/ viagra online

  • Zachary

    Hold the line, please <a href="http://bouw.scouts61.be/nexium-40-mg-price-canada-5xi8">nexium pediatrico</a> The Fed's first hints in May that it may start to pull backfrom its $85 billion dollars-per-month programme led to arebound in the safe-haven yen as investors stampeded out ofemerging markets and commodity currencies.

  • Aubrey

    Would you like to leave a message? <a href="https://bomexperts.com/trental-400mg-dosage-nv76">trental 400 tablet substitute</a> "The music sounds like mine. But certainly, I'm not playing up the Americana elements either," he told Paste. "I'm not having pedal steel and fiddle, but it'll be hyper-romantic and playful more than anything."

  • Norbert

    Punk not dead <a href="https://thaipham.live/roach-doctor-walmart-ynm2">roach doctor walmart</a> We wanted to see what the effect would be of increasing average sleep by just one hour. So we asked seven volunteers, who normally sleep anywhere between six and nine hours, to be studied at the University of Surrey&#039;s Sleep Research Centre.

  • Aaliyah

    Not in at the moment <a href="http://www.mediacenterimac.com/amitriptyline-coupon-dufx">what is amitriptyline hydrochloride 50 mg used for</a> The early entry gave Samsung an undeniable edge, and it adapted fast to a rapidly changing environment. By the mid-1990s, with the economy booming, Samsung made the strategic decision to treat the Chinese market not just as a production base, but to start marketing to China higher-priced electronics, said Nomura researcher Choi Chang-hee, who wrote a history of Samsung's experience in China.

  • Jarred

    Looking for a job <a href="https://thaipham.live/testosterone-enanthate-300-reviews-csxa">hrt testosterone cream </a> The maker of PlayStation game consoles and Bravia TVs loggedan operating profit of 36.36 billion yen ($369.68 million) inthe April-June quarter, topping the 25.3 billion yen April-Juneoperating profit expected by four analysts surveyed by ThomsonReuters I/B/E/S. The company posted an operating profit of 6.3billion yen in the same period last year.

发表评论

博客统计

访问量:5263811

博文总数:750 评论总数:910099

原创126 翻译20 转载604