2

This is an ASP.NET Core default project ConfigureServices method:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

    services.AddMvc();

    // Add application services.
    services.AddTransient<IEmailSender, AuthMessageSender>();
    services.AddTransient<ISmsSender, AuthMessageSender>();
}

My question is how can I access the email service or sms service inside ApplicationDbContext?

Or let's say I will have a custom service built and I register it in the DI like this:

services.AddTransient<ICustomService, CustomService>();

how can I access email service or sms service inside of this?

I assume that the email and sms service must be added to the DI before other services that will use them right?

1 Answer 1

6

Default DI implementation provided with ASP.NET Core supports only constructor injection. Your CustomService class should have ctor that expects dependencies (SMS/Email senders) as parameters:

public class CustomService : ICustomService
{
    public ClassName(IEmailSender emailSender, ISmsSender smsSender)
    {
        // use senders here or store in private variables
    }
}

When you define constructor, note that (from Constructor Injection Behavior section)

  • Constructor injection requires that the constructor in question be public.
  • Constructor injection requires that only one applicable constructor exist. Constructor overloads are supported, but only one overload can exist whose arguments can all be fulfilled by dependency injection.
  • Constructors can accept arguments that are not provided by dependency injection, but these must support default values.

I assume that the email and sms service must be added to the DI before other services that will use them right?

They should be registered in DI container before it will try to construct the first instance of the class that expects it as constructor arguments. As method services.AddTransient<ICustomService, CustomService>(); doesn't instantiate CustomService class, the following it still a valid code:

services.AddTransient<ICustomService, CustomService>();
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();

But it is a good practice to register in order from simple to complicated type.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.