gpt4 book ai didi

c# - 如何在 Nancy 中注入(inject) ClaimsPrincipal

转载 作者:太空宇宙 更新时间:2023-11-03 14:58:29 24 4
gpt4 key购买 nike

我有一个 Nancy 模块和一个装饰器类,它们需要知道 ClaimsPrincipal 才能检索用户的电子邮件地址。所以我将构造函数声明为

public EmailDecorator(IDbConnectionFactory connectionFactory,
IPrincipal principal,
IEmailClient emailClient) : base(connectionFactory)

我正在努力弄清楚的是如何将委托(delegate)人注入(inject)构造函数。我正在使用 Simple Injector for DI,它非常有效。但是如果我重写 ConfigureRequestContainer()方法,它作为 NancyContext 的参数,用于实例化 IPrincipal我得到一个异常(exception)

protected override void ConfigureRequestContainer(
TinyIoCContainer container, NancyContext context)
{
container.Register<IPrincipal>((c, o) => context.CurrentUser);
base.ConfigureRequestContainer(container, context);
}

异常表明简单注入(inject)器不知道 IPrincipal它在默认的 TinyIOC 容器中注册。

The configuration is invalid. Creating the instance for type InvoiceModule failed. The constructor of type EmailDecorator contains the parameter with name 'principal' and type IPrincipal that is not registered. Please ensure IPrincipal is registered, or change the constructor of EmailDecorator.

编辑

我花了太长时间试图解决这个问题,我怀疑答案是停止尝试这样做。在我原来的示例中,我试图将 IPrincipal 注入(inject)到不正确的装饰器构造函数中。相反,我需要注入(inject)某种形式的服务,允许我在调用装饰器中的方法之一时派生 IPrincipal,例如Func<IPrincipal> . Nancy 提供了一种可覆盖的方法 ConfigureRequestContainer()这是为每个请求调用的,因此可能被使用:

protected override void ConfigureRequestContainer(TinyIoCContainer container, NancyContext context)
{
container.Register<Func<IPrincipal>>((c, o) =>
{
return () => context.CurrentUser;
});
}

除了请求容器是 TinyIoCContainer 而我使用的是 SimpleInjector。那么,也许我可以添加一个 SimpleInjector 注册,将解析卸载到请求容器?

_container.RegisterSingleton<Func<IPrincipal>>(() => nancy.Resolve<Func<IPrincipal>>());

实际上没有,nancy与请求容器不是同一个容器。所以也许某个地方有一个容器可以成功解析 IPrincipal 但我不知道如何访问它。练习的目的是避免必须修改 repo 代码的方法签名以包含 ClaimsPrincipal,有点像过去可以调用 Thread.CurrentPrincipal 的日子。 .仍在寻找线索,但将开始修改方法签名以包含 ClaimsPrincipal。

最佳答案

答案是使用IHttpContextAccessor .在 Startup.cs 的 ConfigureServices() 方法中添加一个新的服务定义:

public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IAppSettings>(settings);
services.AddSingleton<IHttpContextAccessor>(new HttpContextAccessor());

}

然后将 app.ApplicationServices 作为参数传递给 Bootstrap :

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IAppSettings settings)
{
var log = ConfigureLogger(settings);
app.UseOwin(buildFunc =>
{
buildFunc.UseMonitoringAndLogging(log, HealthCheckAsync);
buildFunc.UseNancy(cfg =>
cfg.Bootstrapper = new Bootstrapper(env, log, app.ApplicationServices));
});
}

在Bootstrapper类的ApplicationStartup()方法中,在Simple Injector容器中注册服务:

    public Bootstrapper(IHostingEnvironment env, ILogger log, IServiceProvider services)
{
_env = env;
_log = log;
_services = services;
}



_container.Register<IHttpContextAccessor>(() =>
(IHttpContextAccessor) _services.GetService(typeof(IHttpContextAccessor)));

然后在装饰器类中,在构造函数中添加IHttpContextAccessor:

public EmailDecorator(IDbConnectionFactory connectionFactory,
ILogger log,
IHttpContextAccessor httpContextAccessor,
IEmailClient emailClient) : base(connectionFactory, log)
{
_emailClient = emailClient;
_httpContextAccessor = httpContextAccessor;
}

可以从 _httpContextAccessor.HttpContext 属性访问 ClaimsPrincipal

关于c# - 如何在 Nancy 中注入(inject) ClaimsPrincipal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47585008/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com