1

I'm struggling with this concept of dependency injection. Here is one of the articles I am reading:

https://www.dotnettricks.com/learn/dependencyinjection/implementation-asp-net-core-mvc

Here is the first part of my class:

private readonly IConfiguration _configuration;

public Mailgun(IConfiguration configuration) 
{
    _configuration = configuration;
}

IConfiguration contains the connection information needed to connect to the MailGun API wrapper.

And here is where I tried passing the Configuration in Program.cs (mostly as it comes out of the box with a new ASP.NET Core 7 MVC project:

var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddConsole();

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddTransient<IConfiguration, Mailgun>();
builder.Services.AddControllersWithViews();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

This line is where I am attempting to pass the dependency above:

builder.Services.AddTransient<IConfiguration, Mailgun>();

But the error is

Error CS0311 The type 'Mailgun' cannot be used as type parameter 'TImplementation' in the generic type or method 'ServiceCollectionServiceExtensions.AddTransient<TService, TImplementation>(IServiceCollection)'. There is no implicit reference conversion from 'Mailgun' to 'Microsoft.Extensions.Configuration.IConfiguration'.

I understand the error but do not understand how to inject IConfiguration into my class.

Could someone please show me how this is meant to be accomplished?

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
podrick
  • 35
  • 6
  • **You don't need to do anything to use `IConfiguration`.** Its implementation is assigned for you (the configuration is taken from `appsettings.json`). Just remove that line. – SNBS Aug 29 '23 at 11:42
  • `AddTransient` assigns *implementation*, not class that *uses* the service. – SNBS Aug 29 '23 at 11:43

1 Answers1

2

It looks like there's a slight confusion in your code regarding dependency injection and the types being used. Let me help you clarify and correct the code.

In your code, you're trying to inject IConfiguration into the Mailgun class. However, IConfiguration is typically used for configuration settings, and it seems like you actually want to inject some configuration values from IConfiguration into the Mailgun class.

Here's how you can structure your code:

Create a configuration class to hold your MailGun settings:

public class MailgunSettings
{
    // Properties as needed
}

Update your Mailgun class to accept MailgunSettings instead of IConfiguration:

public class Mailgun
{
    private readonly MailgunSettings _mailgunSettings;

    public Mailgun(MailgunSettings mailgunSettings) 
    {
        _mailgunSettings = mailgunSettings;
    }
}

In your Program.cs, configure the MailgunSettings from your configuration and inject it into the Mailgun class:

var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddConsole();

// Load Mailgun settings from configuration
var mailgunSettings = builder.Configuration.GetSection("Mailgun").Get<MailgunSettings>();

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddSingleton(mailgunSettings); // Singleton might be more appropriate for settings
builder.Services.AddTransient<Mailgun>(); // Assuming Mailgun class has no other dependencies
builder.Services.AddControllersWithViews();

var app = builder.Build();

// Other middleware and routing configuration

app.Run();

In your appsettings.json or any configuration source, configure your Mailgun settings:

{
  "Mailgun": {
    "ApiKey": "your-api-key",
    "ApiBaseUrl": "your-api-base-url"
  },
  // Other configuration settings
}

By using this approach, you're injecting the configuration values (MailgunSettings) into the Mailgun class rather than injecting the IConfiguration itself. This allows for better separation of concerns and cleaner code organization.

miskaka
  • 59
  • 4
  • @podrick Also read this: https://stackoverflow.com/a/61726193/20690412 – miskaka Aug 29 '23 at 13:35
  • Could you explain to me how I would now create an instance of **Mailgun** that takes the `MailgunSettings`? Would the `MailgunSettings` instance be passed to one of my **Controllers**? – podrick Aug 30 '23 at 02:15