-
Notifications
You must be signed in to change notification settings - Fork 6k
Update dependency-injection-guidelines.md to suggest avoid singleton for stateless service #47991
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
fad1516
617c939
08e8d2d
ee186a8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -108,7 +108,7 @@ | |
|
|
||
| #### General `IDisposable` guidelines | ||
|
|
||
| - Don't register <xref:System.IDisposable> instances with a transient lifetime. Use the factory pattern instead. | ||
| - Don't register <xref:System.IDisposable> instances with a transient lifetime. Use the factory pattern instead so the solved service can be manually disposed after it is done being used. | ||
| - Don't resolve <xref:System.IDisposable> instances with a transient or scoped lifetime in the root scope. The only exception to this is if the app creates/recreates and disposes <xref:System.IServiceProvider>, but this isn't an ideal pattern. | ||
| - Receiving an <xref:System.IDisposable> dependency via DI doesn't require that the receiver implement <xref:System.IDisposable> itself. The receiver of the <xref:System.IDisposable> dependency shouldn't call <xref:System.IDisposable.Dispose%2A> on that dependency. | ||
| - Use scopes to control the lifetimes of services. Scopes aren't hierarchical, and there's no special connection among scopes. | ||
|
|
@@ -153,6 +153,15 @@ | |
| - Avoid calls to <xref:Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider%2A> when configuring services. Calling `BuildServiceProvider` typically happens when the developer wants to resolve a service when registering another service. Instead, use an overload that includes the `IServiceProvider` for this reason. | ||
| - [Disposable transient services are captured](#disposable-transient-services-captured-by-container) by the container for disposal. This can turn into a memory leak if resolved from the top-level container. | ||
| - Enable scope validation to make sure the app doesn't have singletons that capture scoped services. For more information, see [Scope validation](dependency-injection.md#scope-validation). | ||
| - Only use singleton lifetime for services with their own state that is expensive to create or globally shared. Avoid using singleton lifetime for services which themselves have no state. Most .NET IoC containers use "Transient" as the default scope. Considerations and drawbacks of singletons: | ||
| - **Thread safety**: A singleton must be implemented in a thread-safe way. | ||
|
Check failure on line 157 in docs/core/extensions/dependency-injection-guidelines.md
|
||
| - **Coupling**: It can couple otherwise unrelated requests. | ||
|
Check failure on line 158 in docs/core/extensions/dependency-injection-guidelines.md
|
||
| - **Testing challenges**: Shared state and coupling can make unit testing more difficult. | ||
|
Check failure on line 159 in docs/core/extensions/dependency-injection-guidelines.md
|
||
| - **Memory impact**: A singleton may keep a large object graph alive in memory for the lifetime of the application. | ||
|
Check failure on line 160 in docs/core/extensions/dependency-injection-guidelines.md
|
||
| - **Fault tolerance**: If a singleton or any part of its dependency tree fails, it cannot easily recover. | ||
|
Check failure on line 161 in docs/core/extensions/dependency-injection-guidelines.md
|
||
| - **Configuration reloading**: Singletons generally cannot support "hot reload" of configuration values. | ||
|
Check failure on line 162 in docs/core/extensions/dependency-injection-guidelines.md
|
||
| - **Scope leakage**: A singleton can inadvertently capture scoped or transient dependencies, effectively promoting them to singletons and causing unintended side effects. | ||
|
Check failure on line 163 in docs/core/extensions/dependency-injection-guidelines.md
|
||
| - **Initialization overhead**: When resolving a service, the IoC container needs to look up the singleton instance. If it doesn't already exist, it needs to create it in a thread-safe manner. In contrast, a stateless transient service is very cheap to create and destroy. | ||
|
Check failure on line 164 in docs/core/extensions/dependency-injection-guidelines.md
|
||
|
|
||
| Like all sets of recommendations, you may encounter situations where ignoring a recommendation is required. Exceptions are rare, mostly special cases within the framework itself. | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.