[英]UserManager dependency injection with Owin and Simple Injector
在将Simple Injector添加到我的项目中以创建UserAppManager的实例之后,该实例将在会话的整个生命周期中都存在,我开始收到错误消息:
没有无参数构造函数时出错:
尝试创建“ AuthController”类型的控制器时发生错误。 确保控制器具有无参数的公共构造函数。
无参数构造函数出错:
为了使容器能够创建AuthController,它应该只有一个公共构造函数:它有2个。
我遵循了指南( https://simpleinjector.codeplex.com/discussions/564822 )以避免从Request.GetOwinContext()获取UserManager并使用构造函数来执行它,但是没有运气。 我究竟做错了什么?
启动:
public class Startup
{
public void Configuration(IAppBuilder app)
{
...
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(httpConfig);
DependencyConfig.InjectDependencies(app);
}
}
AuthController:
[RoutePrefix("api/auth")]
public class AuthController : ApiController
{
readonly private AppUserManager _appUserManager;
public AuthController(AppUserManager appUserManager)
{
_appUserManager = appUserManager;
}
}
DependencyConfig:
public class DependencyConfig
{
public static void InjectDependencies(IAppBuilder app)
{
var container = new Container();
container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();
container.Register<AppDbContext>(Lifestyle.Scoped);
container.Register<IUserStore<AppUser>>(() => new UserStore<AppUser>(container.GetInstance<AppDbContext>()), Lifestyle.Scoped);
container.Register<AppUserManager>(Lifestyle.Scoped);
// other service injections
container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
container.Verify();
GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
app.CreatePerOwinContext(() => container.GetInstance<AppUserManager>());
}
}
查看您的代码:
Startup.cs
app.UseWebApi(httpConfig);
DependencyConfig
container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
container.Verify();
GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
对我来说似乎很清楚,Web Api配置和SimpleInjector注册都没有使用相同的HttpConfiguration
实例。
请注意, GlobalConfiguration.Configuration
!= httpConfig
(除非您手动分配了var httpConfig = GlobalConfiguration.Configuration
)。
这样,您的Web API中间件将不了解SimpleInjector,并将使用其默认实现。 因此,创建控制器将失败。
对于Web Api和SimpleInjector注册,请使用相同的HttpConfiguration
:
public class Startup
{
public void Configuration(IAppBuilder app)
{
//...
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(httpConfig);
DependencyConfig.InjectDependencies(app, httpConfig);
}
}
public class DependencyConfig
{
public static void InjectDependencies(IAppBuilder app, HttpConfiguration config)
{
// ...
container.RegisterWebApiControllers(config);
container.Verify();
config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
// ...
}
}
另外,您只需要为控制器提供一个构造函数,就可以将要注入的每个参数都放入其中(删除无参数构造函数)。
app.CreatePerOwinContext
使用此行时,我将非常小心:
app.CreatePerOwinContext(() => container.GetInstance<AppUserManager>());
您正在Owin内部请求一个LifeStyle.Scoped
类型的实例,但是您将默认范围声明为WebApiRequestLifestyle
。 这种生活方式继承自ExecutionContextScopeLifestyle
但是范围本身仅在Web Api请求开始时才开始,因此,我相信它不会出现在Web API之外执行的任何中间件中(也许Steven可以帮助我们阐明这一点)。
您可以考虑使用WebRequestLifestyle
, 但要注意async / await可能存在的问题 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.