In Blazor server, how can I inject a scoped service into the lambda below so that I can read the authenticated user and select a SQL connection string based on the user.
builder.Services.AddDbContextFactory<GlueDbContext>((provider, options) =>
{
var AuthenticationStateProvider = provider.GetService<AuthenticationStateProvider>();
// *** Compiles but FAILS because AuthenticationStateProvider is not a Singleton ***
var user = _authenticationStateProvider.GetAuthenticationStateAsync().Result.User;
//
string sqlConnectString = SomeFunctionDerivingTheConnectionFromTheUser(user);
options.UseMySql(connectionString);
});
CodePudding user response:
Following this link, it should look something like this (I'm typing without IDE so it may contain some typos):
var serviceScopeFactory = provider.GetService<IServiceScopeFactory>(); //IServiceScopeFactory is a singleton, so you can easily get it here
using var scope = serviceScopeFactory.CreateScope();
var authenticationStateProvider = scope.GetService<AuthenticationStateProvider>();
//...
CodePudding user response:
You can't do that. Services.Add.... simply adds classes/interfaces to a collection. It's not till later that the services container gets initialised, and until you use a DI object that an instance of that object gets initialised.
To illustrate the process, here's the code to set up a services container serviceProvider
in a test.
var services = new ServiceCollection();
services.AddDbContextFactory<InMemoryWeatherDbContext>(options => options.UseInMemoryDatabase("WeatherDatabase"));
services.AddSingleton<IDataBroker, ServerDataBroker>();
var serviceProvider = services.BuildServiceProvider();
Whatever you design, it needs rethinking.