Transient "disposable" service language updates (#31738)
parent
6d2205638e
commit
10c72c79ab
|
@ -317,16 +317,15 @@ public IMyService MyService { get; set; }
|
|||
|
||||
## Utility base component classes to manage a DI scope
|
||||
|
||||
<!-- UPDATE 10.0 - PU design is under consideration for .NET 10. -->
|
||||
|
||||
In non-Blazor ASP.NET Core apps, scoped and transient services are typically scoped to the current request. After the request completes, scoped and transient services are disposed by the DI system.
|
||||
|
||||
In interactive server-side Blazor apps, the request scope lasts for the duration of the circuit (the SignalR connection between the client and server), which can result in scoped and transient services living much longer than expected for the lifetime of a single component. Therefore, direct use of scoped services for single component lifetimes should be avoided, and transient services shouldn't be registered or used at all. An alternative approach based on the <xref:Microsoft.AspNetCore.Components.OwningComponentBase> type is described later in this section.
|
||||
In interactive server-side Blazor apps, the DI scope lasts for the duration of the circuit (the SignalR connection between the client and server), which can result in scoped and disposable transient services living much longer than the lifetime of a single component. Therefore, don't directly inject a scoped service into a component if you intend the service lifetime to match the lifetime of the component. Transient services injected into a component that don't implement <xref:System.IDisposable> are garbage collected when the component is disposed. However, injected transient services *that implement <xref:System.IDisposable>* are maintained by the DI container for the lifetime of the circuit, which prevents service garbage collection when the component is disposed and results in a memory leak. An alternative approach for scoped services based on the <xref:Microsoft.AspNetCore.Components.OwningComponentBase> type is described later in this section, and disposable transient services shouldn't be used at all. For more information, see [Design for solving transient disposables on Blazor Server (`dotnet/aspnetcore` #26676)](https://github.com/dotnet/aspnetcore/issues/26676).
|
||||
|
||||
Even in client-side Blazor apps that don't operate over a circuit, services registered with a scoped lifetime are treated as singletons, so they live longer than scoped services in typical ASP.NET Core apps. Client-side transient services can also live longer than expected because there's no request-response-based lifetime to trigger DI system disposal of transient services. Although long-lived transient services are of greater concern on the server, they should generally be avoided as client service registrations as well. Use of the <xref:Microsoft.AspNetCore.Components.OwningComponentBase> type is also recommended for client-side services to control service lifetime.
|
||||
Even in client-side Blazor apps that don't operate over a circuit, services registered with a scoped lifetime are treated as singletons, so they live longer than scoped services in typical ASP.NET Core apps. Client-side disposable transient services also live longer than the components where they're injected because the DI container, which holds references to disposable services, persists for the lifetime of the app, preventing garbage collection on the services. Although long-lived disposable transient services are of greater concern on the server, they should be avoided as client service registrations as well. Use of the <xref:Microsoft.AspNetCore.Components.OwningComponentBase> type is also recommended for client-side scoped services to control service lifetime, and disposable transient services shouldn't be used at all.
|
||||
|
||||
An approach that limits a service lifetime is use of the <xref:Microsoft.AspNetCore.Components.OwningComponentBase> type. <xref:Microsoft.AspNetCore.Components.OwningComponentBase> is an abstract type derived from <xref:Microsoft.AspNetCore.Components.ComponentBase> that creates a DI scope corresponding to the *lifetime of the component*. Using this scope, it's possible to use DI services with a scoped lifetime and have them live as long as the component. When the component is destroyed, services from the component's scoped service provider are disposed as well. This can be useful for services that:
|
||||
|
||||
* Should be reused within a component, as the transient lifetime is inappropriate.
|
||||
* Shouldn't be shared across components, as the singleton lifetime is inappropriate.
|
||||
An approach that limits a service lifetime is use of the <xref:Microsoft.AspNetCore.Components.OwningComponentBase> type. <xref:Microsoft.AspNetCore.Components.OwningComponentBase> is an abstract type derived from <xref:Microsoft.AspNetCore.Components.ComponentBase> that creates a DI scope corresponding to the *lifetime of the component*. Using this scope, a component can inject services with a scoped lifetime and have them live as long as the component. When the component is destroyed, services from the component's scoped service provider are disposed as well. This can be useful for services reused within a component but not shared across components.
|
||||
|
||||
Two versions of <xref:Microsoft.AspNetCore.Components.OwningComponentBase> type are available and described in the next two sections:
|
||||
|
||||
|
|
Loading…
Reference in New Issue