在使用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 app)方法中注释掉了以下行,默认情况下会创建UserManager类:
// app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
Run Code Online (Sandbox Code Playgroud)
相反,我使用了在安装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. …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个"准系统"Web API项目,该项目使用OWIN中间件,Ninject Depencency Injection,最终将在IIS中托管.我按照文章"与ASP.NET Web.API2,OWIN和Ninject建立联系"中的说明进行了操作:http://www.alexzaitzev.pro/2014/11/webapi2-owin-and-ninject.html,除了我使用了一个空的Web应用程序项目,并且在创建项目时没有勾选"包含Web API引用和文件夹".
当我启动新API并发出页面请求时,我会Ninject.ActivationException抛出以下内容:
Run Code Online (Sandbox Code Playgroud)Server Error in '/' Application. Error activating HttpConfiguration More than one matching bindings are available. Matching bindings: 1) binding from HttpConfiguration to method 2) binding from HttpConfiguration to constant value Activation path: 1) Request for HttpConfiguration Suggestions: 1) Ensure that you have defined a binding for HttpConfiguration only once.
刷新浏览器时,此异常消失了.我真的不明白是什么导致了这个异常.从我的观点来看,在OWIN环境和Ninject中对WebAPI缺乏经验,很难知道问题出在哪里.与Ninject一起......?它在OWIN ......?是在WebAPI ......?
这是我的Startup.cs文件的内容:
using System.Web.Http;
using LHD.API_2;
using Microsoft.Owin;
using Microsoft.Owin.Security.OAuth;
using Ninject.Web.Common.OwinHost;
using Ninject.Web.WebApi.OwinHost;
using Owin; …Run Code Online (Sandbox Code Playgroud) 我已将我的Web Api应用程序移植到Web Api 2并安装了ninject web api pacckage.但现在我收到一个错误:
Error activating ModelValidatorProvider using binding from ModelValidatorProvider to NinjectDefaultModelValidatorProvider
A cyclical dependency was detected between the constructors of two services.
Run Code Online (Sandbox Code Playgroud) 我正在使用Ninject for DI和MVC4应用程序中的Ninject.MVC3扩展,特别是版本3.0.0.6.
阅读Ninject维基上的文档,看来创建的对象的生命周期InRequestScope实际上是由ASP.NET控制的,并且要正确清理它们应该注册OnePerRequestHttpModule.
然而,看起来这个doco已经过时了,因为type="Ninject.OnePerRequestModule"/>无法找到.
在另一方面,我读了一些位最近,似乎表明,NinjectHttpApplication已经有涉及OnePerRequest.
我的问题是Ninject.Web.MVC 3.0是否已经处理过这个问题,或者我是否还需要手动将HttpModule添加到我的'web.config'中.
我已将下面的内容添加到我的配置中,一切似乎都在工作,但我根本不知道如何测试对象何时被销毁:
<system.web>
<httpModules>
<add name="OnePerRequestModule" type="Ninject.Web.Common.OnePerRequestHttpModule"/>
</httpModules>
...
Run Code Online (Sandbox Code Playgroud)
我是否需要手动添加OnePerRequestHttpModule或Ninject.Web.MVC为我处理这个?
我已创建和MVC 4 Web应用程序,并决定在此应用程序中使用web api.我正在为MVC Web应用程序使用ninject依赖解析器.现在我想对web api使用这个ninject依赖解析器.但是这里提出的问题mvc IDependencyResolver命名空间是:using System.Web.Mvc
和web api IDependencyResolver是using System.Web.Http.Dependencies
那我怎么解决这个问题呢?
最后我想要这样的东西:
// Use the container and the NinjectDependencyResolver as
// application's resolver
var resolver = new NinjectDependencyResolver(container);
//Register Resolver for MVC
DependencyResolver.SetResolver(resolver);
//Register Resolver for Web Api
GlobalConfiguration.Configuration.DependencyResolver = resolver;
Run Code Online (Sandbox Code Playgroud)