From 88aa3357fd722c23d3091d6103f290dcbcf97f15 Mon Sep 17 00:00:00 2001 From: Tom Longhurst <30480171+thomhurst@users.noreply.github.com> Date: Fri, 31 Oct 2025 11:54:46 +0000 Subject: [PATCH] refactor: replace Dictionary with ConcurrentDictionary for thread-safe property injection --- TUnit.Core/TestDetails.cs | 7 +++---- .../Services/PropertyInitializationOrchestrator.cs | 7 ++++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/TUnit.Core/TestDetails.cs b/TUnit.Core/TestDetails.cs index 15215ce379..b10daeb267 100644 --- a/TUnit.Core/TestDetails.cs +++ b/TUnit.Core/TestDetails.cs @@ -1,3 +1,4 @@ +using System.Collections.Concurrent; using System.Diagnostics.CodeAnalysis; using TUnit.Core.Interfaces; @@ -32,10 +33,8 @@ public partial class TestDetails : ITestIdentity, ITestClass, ITestMethod, ITest public string TestFilePath { get; set; } = ""; public int TestLineNumber { get; set; } public required Type ReturnType { get; set; } - public IDictionary TestClassInjectedPropertyArguments { get; init; } = new Dictionary(); - public List Categories { get; } = - [ - ]; + public IDictionary TestClassInjectedPropertyArguments { get; init; } = new ConcurrentDictionary(); + public List Categories { get; } = []; public Dictionary> CustomProperties { get; } = new(); public Type[]? TestClassParameterTypes { get; set; } diff --git a/TUnit.Engine/Services/PropertyInitializationOrchestrator.cs b/TUnit.Engine/Services/PropertyInitializationOrchestrator.cs index 69a383b6a0..7462566749 100644 --- a/TUnit.Engine/Services/PropertyInitializationOrchestrator.cs +++ b/TUnit.Engine/Services/PropertyInitializationOrchestrator.cs @@ -124,10 +124,11 @@ private async Task InitializeSourceGeneratedPropertyAsync( // Set the property value metadata.SetProperty(instance, resolvedValue); - // Store for potential reuse - if (testContext != null && !testContext.Metadata.TestDetails.TestClassInjectedPropertyArguments.ContainsKey(metadata.PropertyName)) + // Store for potential reuse (using TryAdd for thread-safe concurrent access) + if (testContext != null) { - testContext.Metadata.TestDetails.TestClassInjectedPropertyArguments[metadata.PropertyName] = resolvedValue; + ((ConcurrentDictionary)testContext.Metadata.TestDetails.TestClassInjectedPropertyArguments) + .TryAdd(metadata.PropertyName, resolvedValue); } }