简体   繁体   中英

Getting an InvalidOperationException when using a concrete class as a Controller property .NET Core

When passing MailService to my Controller's constructor my app throws a System.InvalidOperationException . However, when I switch it out for the interface, it works. What is the reason for this?

In Startup.cs

services.AddScoped<IMailService, MailService>();

In my Controller

private IMailService MailService { get; }

public AccountController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager, MailService mailService)
{
    if (userManager == null)
        throw new ArgumentNullException(nameof(userManager));

    if (signInManager == null)
        throw new ArgumentNullException(nameof(signInManager));

    if (mailService == null)
        throw new ArgumentNullException(nameof(mailService));

    this.UserManager = userManager;
    this.SignInManager = signInManager;
    this.MailService= mailService;
}

Many thanks!

services.AddScoped<IMailService, MailService>();

Because of that line. You are telling the DI service to inject an instance of MailService in the constructors when it encounters a parameter in the constructor of type IMailService .

You have nothing defined for injecting (replacing) instances of type MailService .

What you have now is good practice, do not change it. You want to program against interfaces when possible. This is also called interface based programming and there are many benefits.


See also a possibly related question: What does it mean to "program to an interface"?

I noticed this too. Back when we used Unity for DI, it would be fine with resolving a concrete class you requested, even if you had not specifically added it to the container.

With .NET Core dependency injection, it requires that you specifically declare the services you are injecting. Even though it could resolve your concrete class, I'm guessing the decision was made at some point in the development process to require this. So your code would work if you did:

services.AddScoped<MailService>();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM