问题描述
使用重写规则类在依赖注入/范围服务方面有些挣扎。
的重定向类IRule
我还有一个class ActivateRedirects : IRule
{
public void ApplyRule(RewriteContext context)
{
// Do stuff here which relies on CoreSettings (info below)
}
}
类,其中包含各种设置,其中某些设置是CoreSettings
工作所必需的,它在ApplyRule
中初始化如下。
startup.cs
因此您可以在上面看到,var configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddJsonFile(Path.Combine(Directory.GetCurrentDirectory(),"site.json"),optional: false,reloadOnChange: true);
IConfigurationRoot root = configurationBuilder.Build();
CoreSettings s = new CoreSettings();
services.Configure<CoreSettings>(root.GetSection("Website"));
是作为服务创建的,在大多数情况下,我可以使用DI进行消费:
CoreSettings
我已经阅读了几页,了解为什么我不能简单地将DI添加到public class SomeOtherClass{
private CoreSettings Settings;
public SomeOtherClass(Microsoft.Extensions.Options.IOptionsSnapshot<CoreSettings> S)
{
Settings = S.Value;
}
// Do stuff with Settings ....
}
类中,或者为什么在使用ActivateRedirects
中显式传递值,但是我所读的所有内容都在告诉我 做不到 ,我什么都找不到告诉我 可以 的东西!
在被告知重写代码以不需要app.applicationservices.GetrequiredService
进行重写之前,我无法做到这一点,因为其中一个重写规则取决于远程服务器通过{{1 }},CoreSettings
类中需要的是用于创建REST API
的API凭据。
解决方法
可以做您想做的事。我假设您的班级定义如下:
public class ActivateRedirects : IRule
{
private readonly CoreSettings _coreSettings;
public ActivateRedirects(CoreSettings coreSettings)
{
_coreSettings = coreSettings;
}
public void ApplyRule(RewriteContext context)
{
}
}
像以前一样读取配置文件:
services.Configure<CoreSettings>(root.GetSection("Website"));
下一步,设置您的RewriteOptions
:
var coreSettings = app.ApplicationServices.GetRequiredService<IOptions<CoreSettings>>();
var activateRedirects = new ActivateRedirects(coreSettings.Value);
var rewriteOptions = new RewriteOptions();
rewriteOptions.Rules.Add(activateRedirects);
app.UseRewriter(rewriteOptions);
如果您在ActivateRedirects
内放置一个断点并发送请求,您将看到CoreSettings
字段已填充。
更新
我认为这种情况就是IOptionsMonitor<T>
的设计目的。它已注册为单例,但会通知其选项更改。将ActivateRedirects
更改为:
public class ActivateRedirects : IRule
{
private readonly IOptionsMonitor<CoreSettings> _coreSettings;
public ActivateRedirects(IOptionsMonitor<CoreSettings> coreSettings)
{
_coreSettings = coreSettings;
}
public void ApplyRule(RewriteContext context)
{
}
}
并将实例的构造方式更改为:
var coreSettings = app.ApplicationServices.GetRequiredService<IOptionsMonitor<CoreSettings>>();
var activateRedirects = new ActivateRedirects(coreSettings);
对我来说,编辑配置现在可以在CoreSettings
中显示更新的值。一个警告是我不知道该通知过程如何工作。如果最终无法直接在每个请求上读取配置,那么它的伸缩性将很差,因此建议您先对其进行良好的测试。