Reputation: 176
I make a spa on a blazor and when i close the View and call the Dispose method on ther service, it is not completely cleared, because the next time when i switch to the same view, constructor of this service is not called. Service declared as Scoped. I created the simple example.
Some explanations aboout this example. There is a main page - MainView and a second ProfileView, which has a TabControl with two tabs: FirstTabView and SecondTabView. All Views are declared as Transient services and ProfileService is declared as Scoped.
MainView behavior
There is a Number property, which in the constructor (MainViewModel) is infinitely incremented until the Dispose method is called. This method is made for an example of the lifetime of the Transient.
ProfileView behavior
After the first ui render (OnAfterRenderAsync), a fake load is called in the ProfileService.LoadProfileAsync service. After loading, it shows the time the ProfileView was created, the time the service was created (to check if it is created each time) and the time it was last updated. The first tab shows the name and the second shows connections that are constantly updated from ProfileView.
When switching between tabs (First, Second) in TabControl, property subscriptions are deleted and everything works fine, but if I leave ProfileView and navigate to MainView, then i need to release the ProfileService itself, because i don't need it. It is "freed", but the next time navigate to ProfileView page, the service's constructor is not called. And since the constructor is not called from it, then all subscriptions cannot receive their data, because in the Dispose method of this service I called OnCompleted for each field.
Question?
Why isn't the ProfileService constructor called when i navigate to ProfileView if i've called Dispose before?
Upvotes: 1
Views: 2198
Reputation: 30167
You can't call Dispose
to delete an instance of a service.
A Scoped
service lives for the lifetime of the SPA session. Calling Dispose
manually just runs whatever code you have placed in Dispose
. The Scoped instance of the object isn't removed until the Dependency Injection container is destroyed. If you want to limit the life of a Scoped service to the lifetime of a component/page inherit from OwningComponentBase
. Search the Internet for examples of how to use it, there are several.
In Blazor Server:
In Blazor WASM:
There is an article here - https://www.codeproject.com/Articles/5341118/Using-Blazors-OwningComponentBase - that describes how to handle getting services from the Hub Scoped container when using OwningComponent.
Upvotes: 3