0

In my net 7 app, is there any way to utilize the built in IOC container in my rule (that implements IRule), or do I have to resort to manually injecting its dependencies when registering it from the container?

This is what I do now:

app.UseRewriter(new RewriteOptions().Add(new MyRyle()));

What I'm after is something like this, so I don't have to new up the rule myself:

app.UseRewriter(new RewriteOptions().Add<MyRule>())

If that doesn't work, maybe there's a way to do property injection?

Johan
  • 35,120
  • 54
  • 178
  • 293

1 Answers1

0

The default MS DI container does not support property injection (it's not good design). But we can come up with a strategy that will be better than that.

You could create and bind a service that collects all your rules and returns a RewriteOptions. Since your app is already built, you can resolve from the container.

Add the new services and all rules when building your web app.

builder.Services.AddTransient<IRule, MyRule>();
builder.Services.AddTransient<IRewriteOptionsBuilder, RewriteOptionsBuilder>();

Then just resolve the builder when configuring rewrite.

app.UseRewriter(app.Services.GetRequiredService<IRewriteOptionsBuilder>().Build())

Rewrite Builder

public interface IRewriteOptionsBuilder
{
    RewriteOptions Build();
}

class RewriteOptionsBuilder : IRewriteOptionsBuilder
{
    private readonly IEnumerable<IRule> _rewriteRules;

    public RewriteOptionsBuilder(IEnumerable<IRule> rewriteRules)
    {
        _rewriteRules = rewriteRules;
    }

    public RewriteOptions Build()
    {
        var options = new RewriteOptions();

        foreach (IRule rule in _rewriteRules)
        {
            options.Add(rule);
        }

        return options;
    }
}
Hank
  • 1,976
  • 10
  • 15
  • Good idea, thanks. What about just making it as a middleware class and handling it in InvokeAsync? – Johan Mar 19 '23 at 18:39