Reputation: 3980
I have an interface to a send mail async function which I am using for my email functions in my controller class.
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly IEmailSender _emailSender;
public AccountController(UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IEmailSender emailSender)
{
_userManager = userManager;
_signInManager = signInManager;
_emailSender = emailSender;
}
As you see I am using the IEmailSender emailSender
to create the object and setting it to its instance in the routine AccountController
.
The interface is simply made up of one constructor
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace solitude.admin.core.Interfaces
{
public interface IEmailSender
{
Task SendEmailAsync(string email, string subject, string message);
}
}
But the problem is when I come to view my view I get the following error:
InvalidOperationException: Unable to resolve service for type 'solitude.admin.core.Interfaces.IEmailSender' while attempting to activate 'solitude.admin.core.Controllers.AccountController'.
Microsoft.Extensions.Internal.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, bool isDefaultParameterRequired)
Upvotes: 1
Views: 2421
Reputation: 3980
Tim was indeed correct what I had to do was add this following code to my configure startup.cs
services.AddTransient<IEmailSender, AuthMessageSender>();
The class AuthMessageSender is made up of as follows.
// This class is used by the application to send Email and SMS
// when you turn on two-factor authentication in ASP.NET Identity.
// For more details see this link http://go.microsoft.com/fwlink/?LinkID=532713
public class AuthMessageSender : IEmailSender
{
public Task SendEmailAsync(string email, string subject, string message)
{
// Plug in your email service here to send an email.
return Task.FromResult(0);
}
}
This allowed me to call the function from the class as normal I guess old .net new how to handle this can someone explain to me why this has changed in core why do we have to hard wire like this.
Upvotes: 0
Reputation: 6060
You need to register how the DI engine will provide an IEmailSender
. Assuming you are using asp.net core, you do this is in your Startup.cs
in the ConfigureServices
method:
public void ConfigureServices(IServiceCollection services) {
...
services.AddSingleton<IEmailSender, EmailSenderImplementation>();
...
}
This is where EmailSenderImplementation
is a class that implements the IEmailSender
interface.
This registration tells the DI framework how to get an implementation of IEmailSender
. In my example I am telling it to instantiate a single instance of EmailSenderImplementation
and reuse that instance over the lifetime of the application. You might need to use AddTransient
(if you want a new one every time you ask for one) or AddScoped
(if you want a new one for each http request) instead of AddSingleton
depending on how your implementation of IEmailSender
works.
Upvotes: 2