Home > OS >  How to get to DI container in AddControllers
How to get to DI container in AddControllers

Time:07-15

I would like to register in- and outputformatters in DI, however I don't know how to get to the DI container in the AddControllers method:

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddTransient<TexInputFormatter, MyInputFormatter>()
    .AddTransient<TextOutputFormatter, MyOutputFormatter>()
    .AddControllers(c =>
    {
        c.InputFormatters.Clear();
        c.OutputFormatters.Clear();
        
        // How do I get to the DI container here?
        c.InputFormatters.Add(???.GetRequiredService<TextInputFormatter>());
        c.OutputFormatters.Add(???.GetRequiredService<TextOutputFormatter>());
    });

var app = builder.Build();
app.Run();

I did come up with one 'workaround' by declaring app earlier and the capturing it, but I don't like that solution:

WebApplication? app = null;  // Declare app here
var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddTransient<TexInputFormatter, MyInputFormatter>()
    .AddTransient<TextOutputFormatter, MyOutputFormatter>()
    .AddControllers(c =>
    {
        c.InputFormatters.Clear();
        c.OutputFormatters.Clear();
        
        // Use app.Services here
        c.InputFormatters.Add(app!.Services.GetRequiredService<TextInputFormatter>());
        c.OutputFormatters.Add(app!.Services.GetRequiredService<TextOutputFormatter>());
    });

app = builder.Build();
app.Run();

Edit: Ofcourse I could do:

c.InputFormatters.Add(new MyInputFormatter());
c.OutputFormatters.Add(new MyOutputFormatter());

However, both formatters have a bunch of other dependencies and constructor arguments I want DI to resolve for me.

How would I go about this?

CodePudding user response:

You need a IServiceProvider to get something from your ServiceContainer. To do that you need to build it.

You could use something like that

builder.Services.BuildServiceProvider();

However i read somewhere that this is not the right way to do it (You should not build the provider twice).

Related: For services you could do:

builder.Services.AddSingletion<IFoo, MyService>(serviceProvider => serviceProvider.GetRequiredService<IFoo2>();...);

CodePudding user response:

You don't need DI for adding input or output formatters. just adding new instance should be fine.

check this article and this one for more details:

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddControllers(c =>
    {
        c.InputFormatters.Clear();
        c.OutputFormatters.Clear();
        
        // How do I get to the DI container here?
        c.InputFormatters.Add(new MyInputFormatter());
        c.OutputFormatters.Add(new MyOutputFormatter());
    });

var app = builder.Build();
app.Run();
  • Related