Struggling a little with Dependency Injection/Scoped Services with a rewrite rule class.
I have a redirects class which implements IRule
class ActivateRedirects : IRule
{
public void ApplyRule(RewriteContext context)
{
// Do stuff here which relies on CoreSettings (info below)
}
}
I also have a CoreSettings class which contains various settings, some of which are required for ApplyRule to work, it is initialised in startup.cs as follows.
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"));
So you can see above, CoreSettings is created as a Service, which in most cases I can consume with DI:
public class SomeOtherClass{
private CoreSettings Settings;
public SomeOtherClass(Microsoft.Extensions.Options.IOptionsSnapshot<CoreSettings> S)
{
Settings = S.Value;
}
// Do stuff with Settings ....
}
I have read up on several pages on why I can't simply add DI to the ActivateRedirects Class, or explicitly pass the value in using app.ApplicationServices.GetRequiredService but everything I have read is telling what I can't do, I can't find anything to tell me what I can!!
Before I am told to rewrite the code to not require CoreSettings for Rewriting, I can't do that because one of the rewrite rules depends on a condition which is set by a remote server via a REST API and what is needed in the CoreSettings class is the API credentials used to create the REST Client.
It is possible to do what you want. I'll assume your class is defined as follows:
Read the configuration file, as before:
Next, setup your
RewriteOptions:If you put a breakpoint inside
ActivateRedirects, and send a request, you'll see theCoreSettingsfield has been populated.Update
I think this scenario is what
IOptionsMonitor<T>might be designed for. It's registered as a singleton, but is notified of options changes. ChangeActivateRedirectsto:and change how the instance is constructed to:
For me, editing the configuration does now show updated values in
CoreSettings. One caveat is I don't know how that notification process works. If this ends up reading the configuration directly on each request, then it will scale really poorly, so I'd advise giving it a good test first.