Reputation: 67195
Okay, I'm obviously doing something stupid here but I can't seem to find it.
I'm writing my first Razor Pages app and created an EmailSender
class, which implements IEmailSender
. In addition, the EmailSender
constructor accepts an EmailSettings
parameter. EmailSettings
is implemented as follows.
appsettings.json
"EmailSettings": {
"Host": "****.*****.com",
"Port": "587",
"UserName": "****@**********.com",
"Password": "***********",
"FromAddress": "****@**********.com",
"EnableSsl": "true"
},
EmailSettings.cs
public class EmailSettings
{
public string Host { get; set; }
public int Port { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string FromAddress { get; set; }
public bool EnableSsl { get; set; }
}
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// ...
services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));
services.AddSingleton<IEmailSender, EmailSender>();
}
This follows the basic approach taken from an article I read. But when I run the app, I get an immediate exception:
System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Identity.UI.Services.IEmailSender Lifetime: Transient ImplementationType: Bamtok.Services.EmailSender': Unable to resolve service for type 'Bamtok.Services.EmailSettings' while attempting to activate 'Bamtok.Services.EmailSender'.)'
Somehow, it is not able to instantiate an EmailSettings
instance to pass to the EmailSender
constructor.
Can anyone see what I'm missing?
Upvotes: 2
Views: 612
Reputation: 247018
Configure<T>
registers IOptions<EmailSettings>
and, as you stated, you injected EmailSettings
into the dependent class.
You can either leave the class as is and refactor Startup
public void ConfigureServices(IServiceCollection services) {
// ...
EmailSettings settings = Configuration.GetSection("EmailSettings").Get<EmailSettings>();
services.AddSingleton(settings);
services.AddSingleton<IEmailSender, EmailSender>();
}
Or update the class to expect the IOptions<T>
dependency
public class EmailSender : IEmailSender {
private readonly EmailSettings emailSettings;
public EmailSender(IOptions<EmailSettings> emailSettings) {
this.emailSettings = emailSettings.Value;
}
//...
}
The difference between the former over the latter suggestion is that the implementation will not be coupled to framework concerns.
Upvotes: 1