英文:
Reference a service in object construction before the service is built. C#
问题
builder.Services.AddSingleton<RunningGameService>();
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("GameGroupsAuthorisationConnect", policy =>
{
policy.Requirements.Add(new GameGroupsAuthorisationConnectRequirement());
});
});
Hi,
我遇到的问题是,GameGroupsAuthorisationConnectRequirement 依赖于 RunningGameService,因此需要在构造函数中引用它。
对此我感到有些困惑。
提前感谢。
英文:
builder.Services.AddSingleton<RunningGameService>();
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("GameGroupsAuthorisationConnect", policy =>
{
policy.Requirements.Add(new GameGroupsAuthorisationConnectRequirement());
});
});
Hi,
The problem I have is that the GameGroupsAuthorisationConnectRequirement is dependent on RunningGameService, and hence it requires a reference to it in the constructor.
I'm a tad lost with this.
Thanks in advance.
答案1
得分: 2
要求不应依赖于服务;它只是定义了适用于授权的参数。
来自文档
授权要求是一组数据参数,策略可以使用它们来评估当前用户主体。
例如:
public class GameGroupsAuthorisationConnectRequirement : IAuthorizationRequirement
{
// 如果适用,可以添加属性。
}
处理该要求的是相应的AuthorizationHandler
,该处理程序可以注入服务。
public class GameGroupsAuthorisationConnectRequirementHandler
: AuthorizationHandler<GameGroupsAuthorisationConnectRequirement>
{
public GameGroupsAuthorisationConnectRequirementHandler(
RunningGameService runningGameService
/* 在此注入其他服务 */
)
{
// ...
}
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context, GameGroupsAuthorisationConnectRequirement requirement
)
{
// ...
context.Succeed(requirement);
return Task.CompletedTask;
}
}
注册该处理程序如下。这样做可以从 DI 容器中解析其服务。
builder.Services.AddSingleton<IAuthorizationHandler, GameGroupsAuthorisationConnectRequirementHandler>();
您定义策略的方式可以保持不变。
options.AddPolicy("GameGroupsAuthorisationConnect", policy =>
{
policy.Requirements.Add(new GameGroupsAuthorisationConnectRequirement());
});
英文:
A requirement should not depend on a service; it just defines the parameters that are applicable for the authorization.
From the documentation
> An authorization requirement is a collection of data parameters that a policy can use to evaluate the current user principal.
For example
public class GameGroupsAuthorisationConnectRequirement : IAuthorizationRequirement
{
// Any properties in case applicable.
}
It is the accompanying AuthorizationHandler
that deals with the requirement that can have services injected.
public class GameGroupsAuthorisationConnectRequirementHandler
: AuthorizationHandler<GameGroupsAuthorisationConnectRequirement>
{
public GameGroupsAuthorisationConnectRequirementHandler(
RunningGameService runningGameService
/* Inject other services here */
)
{
// ...
}
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context, GameGroupsAuthorisationConnectRequirement requirement
)
{
// ...
context.Succeed(requirement);
return Task.CompletedTask;
}
}
That handler gets registered as below. Doing so it gets its services resolved from the DI container.
builder.Services.AddSingleton<IAuthorizationHandler, GameGroupsAuthorisationConnectRequirementHandler>();
See Dependency injection in requirement handlers in ASP.NET Core.
The way you defined your policy can stay as-is.
options.AddPolicy("GameGroupsAuthorisationConnect", policy =>
{
policy.Requirements.Add(new GameGroupsAuthorisationConnectRequirement());
});
答案2
得分: 1
使用接受实例而不是泛型参数的 AddSingleton
重载,就像这样:
// 显然,您需要在这里满足此服务的所需构造函数参数...
var rgService = new RunningGameService(...);
builder.Services.AddSingleton<RunningGameService>(rgService);
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("GameGroupsAuthorisationConnect", policy =>
{
policy.Requirements.Add(new GameGroupsAuthorisationConnectRequirement(rgService));
});
});
英文:
Use an overload of AddSingleton
that accepts an instance instead of a generic parameter, like this:
// Obviously you need to satisfy _this_ service's required constructor params here...
var rgService = new RunningGameService(...);
builder.Services.AddSingleton<RunningGameService>(rgService);
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("GameGroupsAuthorisationConnect", policy =>
{
policy.Requirements.Add(new GameGroupsAuthorisationConnectRequirement(rgService));
});
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论