Reputation: 553
I am working an ASP.NET Core 2.1 project where I need to register and then use a singleton service inside of Startup.ConfigureServices.
I have the following code:
public void ConfigureServices(IServiceCollection services)
{
//....
//....
services.AddSingleton<IMyService,MyService>();
var serviceProvider = services.BuildServiceProvider();
var myService = serviceProvider.GetService<IMyService>();
services.AddDbContext<MyDbContext>(options => options.UseMySql(myService.DBConnectionString));
}
The above code works fine for me to be able to use "MyService" inside ConfigureServices. However later in my application when I try and use MyService the constructor of MyService is being called again. Why is it not using the instance that was already created since I registered the class using AddSingleton
?
EDIT: I decided to edit to add my end objective to see if maybe there is a different way to get it done. My singleton service provides access to a few settings that could come from 2 different places. One of those settings is a DB connection string. I need that connection string in ConfigureServices so I have it when I call services.AddDbContext
. I also want to do some logging in the service that gets configuration settings which means I need to get the ILoggerFactory as well.
Upvotes: 4
Views: 5730
Reputation: 247098
Calling BuildServiceProvider
from ConfigureServices
will result in an additional copy of singleton services being created.
Use another approach that defers the access to the service provider in this particular case. AddDbContext
has an overload that allows for such a case, where the service provider is provided as part of the options action delegate.
//...
services.AddSingleton<IMyService, MyService>();
services.AddDbContext<MyDbContext>((serviceProvider, options) =>
options.UseMySql(serviceProvider.GetRequiredService<IMyService>().DBConnectionString)
);
//....
Upvotes: 9
Reputation: 52240
AddSingleton
tells Unity to construct it once. That "once" is in addition to any constructors that you invoke directly in your code.
If you want to re-use the instance you created, use AddInstance
instead.
var serviceProvider = services.BuildServiceProvider();
var myService = serviceProvider.GetService<IMyService>();
services.AddInstance<IMyService>(myService);
services.AddDbContext<MyDbContext>(options => options.UseMySql(myService.DBConnectionString));
Upvotes: 0