I have an issue with Blazor Server:
my DI always get the same ID (instance) on the component's button click
For example: ILoginService.ID = "123"
When i click a button - if the login fails , and retry it will have the same instance ID ="123"
The dependency injection was defined below:
I am aware that if I refresh the page, the DI will work as expected (because it is scope service - new every request) . but it's not fit on my scenario.
I have to refresh the DI object only before or after the button click, so i have a new instance each button click
Is there a way to refresh the DI object only
Already changed the lifetime of DI to transient. Still not working
I was expecting the following
Before Click: ILoginService.ID = "123"
Then Login failed Retry Click ILoginService.ID = "456"
In Blazor Server, components may reuse the same instance of the component upon button clicks, which can affect the retrieval and management of service instances. Even if the service is transient, a new service instance might not be created due to component caching mechanisms.
So, to ensure that a new LoginService
instance is obtained with each button click, you can create a new scope by using IServiceScopeFactory.
Below is my test demo:
LoginService:
public class LoginService : ILoginService
{
public string ID { get; private set; } = Guid.NewGuid().ToString();
// ...
}
Login.razor:
@page "/login"
@rendermode InteractiveServer
@inject IServiceScopeFactory ScopeFactory
<h3>Test</h3>
<button @onclick="HandleLogin">Login</button>
<p> ID: @id</p>
@code {
private string id;
private async Task HandleLogin()
{
using (var scope = ScopeFactory.CreateScope())
{
var loginService = scope.ServiceProvider.GetRequiredService<ILoginService>();
id = loginService.ID;
}
}
}
Also register the service as:
builder.Services.AddScoped<ILoginService, LoginService>();
My test results:
First click:
Second click: