refactor: PropertyInjector complexity and allocation improvements#4931
Conversation
2e6f829 to
7ee0ba4
Compare
Code reviewOverall this is a clean, well-executed refactoring. The method extractions reduce cyclomatic complexity, the Design observation:
|
7ee0ba4 to
31bdcca
Compare
31bdcca to
371889f
Compare
371889f to
86bb181
Compare
- Cache PropertyInfo lookups via static ConcurrentDictionary to avoid repeated reflection calls in source-gen paths - Extract InjectPropertiesFromPlanAsync and RecurseIntoPropertyValueAsync to reduce cyclomatic complexity of InjectPropertiesRecursiveAsync - Extract CreateSourceGeneratedDataGeneratorMetadata to fix duplicate PropertyHelper.GetPropertyInfo call (was called twice per property) - Extract RentVisitedDictionary/ReturnVisitedDictionary for pool ops - Use PropertyInitializationContext factory methods instead of manual object initializers, reducing duplication across 4 call sites - Replace foreach with indexed for loops to avoid enumerator allocations - Simplify GetInitializedDataSourceAsync with null-coalescing operator - Remove redundant condition checks where HasProperties already implies properties exist - Convert ResolveAndCachePropertiesCoreAsync from async to synchronous Task return to avoid unnecessary state machine allocation Closes #4897
466ebca to
0690fd0
Compare
Summary
ConcurrentDictionary<(Type, string), PropertyInfo?>to eliminate repeatedGetPropertycalls inInjectSourceGeneratedPropertyAsyncandRecurseIntoNestedPropertiesCoreAsyncCreateDataGeneratorMetadatawherePropertyHelper.GetPropertyInfowas called twice for the same property (once forReflectionInfo, once forGetterlambda) -- now resolved once and reusedPropertyInitializationContext(ForSourceGenerated,ForReflection,ForCaching,ForReflectionCaching) instead of manual object initializers across 4 call sites, reducing duplicationInjectPropertiesFromPlanAsync,RecurseIntoPropertyValueAsync,CreateSourceGeneratedDataGeneratorMetadata,RentVisitedDictionary/ReturnVisitedDictionaryto reduce cyclomatic complexityHasPropertieswas already verified before checkingSourceGeneratedProperties.Length > 0 || ReflectionProperties.Length > 0ResolveAndCachePropertiesCoreAsyncfrom async to synchronous Task return to avoid unnecessary state machine allocationGetInitializedDataSourceAsyncwith null-coalescing operatorAll changes are pure refactoring -- behavior is preserved exactly.
Closes #4897
Test plan
dotnet build TUnit.Engine/TUnit.Engine.csprojsucceeds on all TFMs (netstandard2.0, net8.0, net9.0, net10.0)