From 508bb71492a1fd02b5cd91843ee3ab5a96982ded Mon Sep 17 00:00:00 2001 From: abhiramch018 Date: Tue, 25 Nov 2025 17:47:47 +0530 Subject: [PATCH 1/2] docs: clarify thread safety of service resolution in .NET dependency injection ### Summary Clarified that resolving services from the built-in .NET dependency injection (DI) container is thread-safe. ### Changes - Updated the **Thread safety** section in `dependency-injection-guidelines.md`. - Added explicit statement that: - Service resolution via `IServiceProvider` and `IServiceScope` is thread-safe. - Service implementations themselves must still handle internal concurrency. - Added a note block for clarity. ### Motivation Resolves issue #47086 by explicitly documenting DI service resolution thread safety, which was previously implied but not stated. --- .../extensions/dependency-injection-guidelines.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/core/extensions/dependency-injection-guidelines.md b/docs/core/extensions/dependency-injection-guidelines.md index b813f82b612ff..03505ef178f7d 100644 --- a/docs/core/extensions/dependency-injection-guidelines.md +++ b/docs/core/extensions/dependency-injection-guidelines.md @@ -139,9 +139,16 @@ The following third-party containers can be used with ASP.NET Core apps: ## Thread safety -Create thread-safe singleton services. If a singleton service has a dependency on a transient service, the transient service may also require thread safety depending on how it's used by the singleton. +Create thread-safe singleton services. If a singleton service has a dependency on a transient service, the transient service may also require thread safety depending on how it's used by the singleton. The factory method of a singleton service, such as the second argument to [AddSingleton\(IServiceCollection, Func\)](xref:Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton%2A), doesn't need to be thread-safe. Like a type (`static`) constructor, it's guaranteed to be called only once by a single thread. + +Additionally, the process of **resolving services** from the built-in .NET dependency injection (DI) container is **thread-safe**. +Once an `IServiceProvider` or `IServiceScope` has been built, it's safe to resolve services concurrently from multiple threads. + +> [!NOTE] +> Thread safety of the DI container itself only guarantees that constructing and resolving services is safe. +> It doesn't make the resolved service instances themselves thread-safe. +> Any service (especially singletons) that holds shared mutable state must implement its own synchronization logic if accessed concurrently. -The factory method of a singleton service, such as the second argument to [AddSingleton\(IServiceCollection, Func\)](xref:Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton%2A), doesn't need to be thread-safe. Like a type (`static`) constructor, it's guaranteed to be called only once by a single thread. ## Recommendations From 15cce2b4b62a751208cb1eb106e0714f4bd17cad Mon Sep 17 00:00:00 2001 From: "Meaghan Osagie (Lewis)" Date: Wed, 26 Nov 2025 11:24:22 -0800 Subject: [PATCH 2/2] Remove extra line Clarify thread safety and recommendations for DI usage. --- docs/core/extensions/dependency-injection-guidelines.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/core/extensions/dependency-injection-guidelines.md b/docs/core/extensions/dependency-injection-guidelines.md index 03505ef178f7d..166c9afcbc109 100644 --- a/docs/core/extensions/dependency-injection-guidelines.md +++ b/docs/core/extensions/dependency-injection-guidelines.md @@ -149,7 +149,6 @@ Once an `IServiceProvider` or `IServiceScope` has been built, it's safe to resol > It doesn't make the resolved service instances themselves thread-safe. > Any service (especially singletons) that holds shared mutable state must implement its own synchronization logic if accessed concurrently. - ## Recommendations - `async/await` and `Task` based service resolution isn't supported. Because C# doesn't support asynchronous constructors, use asynchronous methods after synchronously resolving the service.