I have an ASP.NET Core 3.1 based app. During the app startup, in the ConfigureServices(IServiceCollection services) I want to register my services. But during configuring services, I want to boot the app based on settings found in the database.
Here is my code
public void ConfigureServices(IServiceCollection services)
{
// Register context
services.AddDbContext<AppDbContext>(options =>
{
options.UseMySql(Configuration.GetConnectionString("MySqlServerConnection"));
});
// Reister the setting provider
services.AddSingleton<IAppSetting, AppSettings>();
// Create a resolver which is WRONG!!
var resolver = services.BuildServiceProvider();
var setting = resolver.GetService<IAppSetting>();
List<string> allowedCors = new List<string>()
{
setting.MainUrl.ToString()
};
if (setting.HasCustomAssetsUri)
{
allowedCors.Add(settings.AssetsUrl.ToString());
}
if (settings.HasCustomPhotosUri)
{
allowedCors.Add(settings.PhotosUrl.ToString());
}
services.AddCors(options =>
{
options.AddPolicy("AllowSubDomainTraffic",
builder =>
{
builder.WithOrigins(allowedCors.ToArray())
.AllowAnyHeader()
.AllowAnyMethod();
});
});
// More services
}
As you can see in the above code, I register the IAppSetting but I immediately want to use to access the database so get the current configuration. I am currently calling services.BuildServiceProvider() to create a new resolver in which I can then use it to create an instance of the IAppSetting.
My AppSetting implementation depends on the AppDbContext which is also registered. Here is my AppSetting
public class AppSetting : IAppSetting
{
private AppDbContext context;
public AppSetting(AppDbContext context)
{
this.context = context;
}
// methods...
}
Calling BuildServiceProvider() will result in an additional copy of singleton services being created. so I am trying to avoid having to do this.
How can I correctly register and then resolve IAppSetting in the ConfigureServices() method so I can use it to access the settings found in the database?
Updated
I attempted to use the solution presented by Nkosi, but getting the following error
System.InvalidOperationException: 'Cannot resolve scoped service 'IAppSetting' from root provider.'
Here is the full stack trace.
This exception was originally thrown at this call stack:
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(System.Type, Microsoft.Extensions.DependencyInjection.IServiceScope, Microsoft.Extensions.DependencyInjection.IServiceScope)
Microsoft.Extensions.DependencyInjection.ServiceProvider.Microsoft.Extensions.DependencyInjection.ServiceLookup.IServiceProviderEngineCallback.OnResolve(System.Type, Microsoft.Extensions.DependencyInjection.IServiceScope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(System.Type, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(System.Type)
Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(System.IServiceProvider, System.Type)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(Microsoft.Extensions.DependencyInjection.ServiceLookup.FactoryCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext)
...
[Call Stack Truncated]
AppSettingto begin wit. Use the configuration system to load settings from the database instead.IConfigurationobject passed to Startup