将 UserManager 传递给 ConfigureServices MVC 6 中的 AuthorizationHandler
Pass UserManager to an AuthorizationHandler in ConfigureServices MVC 6
给定以下 class 与 UserManager 的 DI
public class AccountAuthorizationHandler : AuthorizationHandler<OperationAuthorizationRequirement, AuthorisedAccount>
{
private readonly UserManager<ApplicationUser> userManager;
public AccountAuthorizationHandler(UserManager<ApplicationUser> userManager)
{
this.userManager = userManager;
}
protected override void Handle(AuthorizationContext context,
OperationAuthorizationRequirement requirement,
AuthorisedAccount resource)
{
// Pull the user ID claim out from the context.User
var userId = context.User.GetUserId();
// Get the current user's account numbers.
var user = userManager.Users
.Include(u => u.AuthorisedAccounts)
.Where(u => u.Id == userId)
.FirstOrDefault();
//Now check if the user's account numbers match the resource accountNumber, and
foreach( var authorizedAccount in user.AuthorisedAccounts)
{
if ((resource.AccountNo == authorizedAccount.AccountNo) &&
(requirement == Operations.Read))
context.Succeed(requirement);
}
}
}
我想在 ConfigureServices
中实例化它,但看起来我需要提供 Usermanager。即责任似乎又回到了调用者身上。
services.AddInstance<IAuthorizationHandler>
(new AccountAuthorizationHandler(I want to add UserManager here));
我猜我以为 AuthorizationHandler 会神奇地解决依赖关系本身
我该怎么做
谢谢
tldr;
您使用了错误的重载。
尝试这样的事情:
services.AddTransient<IAuthorizationHandler, AccountAuthorizationHandler>();
在依赖注入中,有很多不同的概念,你使用的是单例的等价物。
有关依赖注入的更多详细信息
单例
有两种方法可以通过 ASP.NET 依赖注入来声明单例。
要么您自己使用 services.AddInstance<T>(...)
提供实例,要么让系统为您构建它并控制其生命周期,以便永远构建该单个实例。
这样做是这样的:
services.AddSingleton<TInterface, TImplementation>()
短暂的生命周期
每次请求这种类型的依赖项时,它都会new
再次启动该对象。没有两个实例是相等的,因为它们总是会被重新创建。
services.AddTransient<TInterface, TImplementation>()
范围
此时,我们请求每个请求一个对象。它是 Transient 和 Singleton 的混合体,但我们只会 new
每个 HTTP 请求一次对象。
services.AddScoped<TInterface, TImplementation>()
结论
依赖注入从一开始就内置在框架中。从安全到模型绑定的一切都可以通过正确的接口和正确的生命周期进行重载。
您应该花一点时间复习一下您对依赖注入的了解,然后再进行得太快。如果时间不够,请使用此 post 中提供的信息。它将足够好让你开始。
给定以下 class 与 UserManager 的 DI
public class AccountAuthorizationHandler : AuthorizationHandler<OperationAuthorizationRequirement, AuthorisedAccount>
{
private readonly UserManager<ApplicationUser> userManager;
public AccountAuthorizationHandler(UserManager<ApplicationUser> userManager)
{
this.userManager = userManager;
}
protected override void Handle(AuthorizationContext context,
OperationAuthorizationRequirement requirement,
AuthorisedAccount resource)
{
// Pull the user ID claim out from the context.User
var userId = context.User.GetUserId();
// Get the current user's account numbers.
var user = userManager.Users
.Include(u => u.AuthorisedAccounts)
.Where(u => u.Id == userId)
.FirstOrDefault();
//Now check if the user's account numbers match the resource accountNumber, and
foreach( var authorizedAccount in user.AuthorisedAccounts)
{
if ((resource.AccountNo == authorizedAccount.AccountNo) &&
(requirement == Operations.Read))
context.Succeed(requirement);
}
}
}
我想在 ConfigureServices
中实例化它,但看起来我需要提供 Usermanager。即责任似乎又回到了调用者身上。
services.AddInstance<IAuthorizationHandler>
(new AccountAuthorizationHandler(I want to add UserManager here));
我猜我以为 AuthorizationHandler 会神奇地解决依赖关系本身
我该怎么做
谢谢
tldr;
您使用了错误的重载。
尝试这样的事情:
services.AddTransient<IAuthorizationHandler, AccountAuthorizationHandler>();
在依赖注入中,有很多不同的概念,你使用的是单例的等价物。
有关依赖注入的更多详细信息
单例
有两种方法可以通过 ASP.NET 依赖注入来声明单例。
要么您自己使用 services.AddInstance<T>(...)
提供实例,要么让系统为您构建它并控制其生命周期,以便永远构建该单个实例。
这样做是这样的:
services.AddSingleton<TInterface, TImplementation>()
短暂的生命周期
每次请求这种类型的依赖项时,它都会new
再次启动该对象。没有两个实例是相等的,因为它们总是会被重新创建。
services.AddTransient<TInterface, TImplementation>()
范围
此时,我们请求每个请求一个对象。它是 Transient 和 Singleton 的混合体,但我们只会 new
每个 HTTP 请求一次对象。
services.AddScoped<TInterface, TImplementation>()
结论
依赖注入从一开始就内置在框架中。从安全到模型绑定的一切都可以通过正确的接口和正确的生命周期进行重载。
您应该花一点时间复习一下您对依赖注入的了解,然后再进行得太快。如果时间不够,请使用此 post 中提供的信息。它将足够好让你开始。