URLRewrite中间件,它取决于Config依赖项注入/作用域服务 .Net核心

问题描述

使用重写规则类在依赖注入/范围服务方面有些挣扎。

我有一个实现view

重定向
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字段已填充。

A screenshot showing an injected setting in the ActivateRedirects class.

更新

我认为这种情况就是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中显示更新的值。一个警告是我不知道该通知过程如何工作。如果最终无法直接在每个请求上读取配置,那么它的伸缩性将很差,因此建议您先对其进行良好的测试。