Reputation: 6029
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?
Upvotes: 2
Views: 4837
Reputation: 49789
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.
Upvotes: 6