🔍 Duplicate Code Detected: TestingPlatformBuilderHook Boilerplate Pattern
Analysis of commit 372c5f1
Summary
Detected 10+ nearly identical TestingPlatformBuilderHook classes across Platform extensions. Each class follows the same boilerplate pattern with only minor variations (namespace, method call, XML documentation). This represents significant structural duplication that increases maintenance burden and violates DRY principles.
Duplication Details
Pattern: TestingPlatformBuilderHook Boilerplate
-
Severity: High
-
Occurrences: 10 instances
-
Total Lines: ~206 lines of mostly duplicated code
-
Locations:
src/Platform/Microsoft.Testing.Extensions.TrxReport/TestingPlatformBuilderHook.cs
src/Platform/Microsoft.Testing.Extensions.AzureFoundry/TestingPlatformBuilderHook.cs
src/Platform/Microsoft.Testing.Extensions.Retry/TestingPlatformBuilderHook.cs
src/Platform/Microsoft.Testing.Extensions.Telemetry/TestingPlatformBuilderHook.cs
src/Platform/Microsoft.Testing.Extensions.CrashDump/TestingPlatformBuilderHook.cs
src/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/TestingPlatformBuilderHook.cs
src/Platform/Microsoft.Testing.Extensions.MSBuild/TestingPlatformBuilderHook.cs
src/Platform/Microsoft.Testing.Extensions.HangDump/TestingPlatformBuilderHook.cs
src/Platform/Microsoft.Testing.Extensions.HotReload/TestingPlatformBuilderHook.cs
src/Platform/Microsoft.Testing.Extensions.HtmlReport/TestingPlatformBuilderHook.cs
-
Code Sample (TrxReport):
public static class TestingPlatformBuilderHook
{
/// <summary>
/// Adds TrxReport support to the Testing Platform Builder.
/// </summary>
/// <param name="testApplicationBuilder">The test application builder.</param>
/// <param name="_">The command line arguments.</param>
public static void AddExtensions(ITestApplicationBuilder testApplicationBuilder, string[] _)
=> testApplicationBuilder.AddTrxReportProvider();
}
-
Code Sample (HangDump - with attribute variation):
public static class TestingPlatformBuilderHook
{
/// <summary>
/// Adds HangDump support to the Testing Platform Builder.
/// </summary>
/// <param name="testApplicationBuilder">The test application builder.</param>
/// <param name="_">The command line arguments.</param>
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
public static void AddExtensions(ITestApplicationBuilder testApplicationBuilder, string[] _)
=> testApplicationBuilder.AddHangDumpProvider();
}
Impact Analysis
- Maintainability: Any structural change to the hook pattern requires updating 10+ files identically
- Bug Risk: Inconsistencies can arise when one file is updated but others are missed
- Code Bloat: ~180+ lines of unnecessary duplication
- Onboarding: New extensions must replicate this boilerplate, increasing friction
Refactoring Recommendations
Option 1: Source Generator (Recommended)
Create a Roslyn source generator that auto-generates TestingPlatformBuilderHook classes based on assembly-level attributes:
// In each extension assembly:
[assembly: TestingPlatformExtension(
ExtensionMethodName = nameof(TrxReportExtensions.AddTrxReportProvider))]
// Generator produces:
public static class TestingPlatformBuilderHook
{
public static void AddExtensions(ITestApplicationBuilder builder, string[] _)
=> builder.AddTrxReportProvider();
}
Benefits:
- Zero manual boilerplate
- Compile-time validation
- Single source of truth for hook pattern
- Automatic handling of platform attributes
Estimated effort: 8-12 hours
Option 2: Convention-Based Reflection
Use reflection in TestingPlatformAutoRegisteredExtensions to discover and invoke extension methods by convention:
// Discovery logic:
var extensionMethod = assembly.GetTypes()
.SelectMany(t => t.GetMethods())
.FirstOrDefault(m => m.Name.StartsWith("Add") &&
m.Name.EndsWith("Provider"));
Benefits:
- Eliminates hook classes entirely
- Runtime flexibility
Drawbacks:
- Runtime overhead
- Less type-safe
- Harder to debug
Estimated effort: 4-6 hours
Option 3: Base Class with Template Method
Create an abstract base with virtual methods:
public abstract class TestingPlatformBuilderHookBase
{
public void AddExtensions(ITestApplicationBuilder builder, string[] args)
=> AddExtensionsCore(builder, args);
protected abstract void AddExtensionsCore(ITestApplicationBuilder builder, string[] args);
}
Benefits:
- Reduces duplication
- Maintains type safety
Drawbacks:
- Still requires a class per extension
- Less elegant than generator approach
Estimated effort: 2-3 hours
Implementation Checklist
Analysis Metadata
- Analyzed Files: 895 C# source files
- Detection Method: Semantic code analysis + pattern matching
- Commit: 372c5f1
- Analysis Date: 2026-05-25T05:45:53.799+00:00
- Pattern Type: Structural duplication (boilerplate)
Generated by Duplicate Code Detector · ● 1.6M · ◷
Add this agentic workflows to your repo
To install this agentic workflow, run
gh aw add githubnext/agentics/workflows/duplicate-code-detector.md@main
🔍 Duplicate Code Detected: TestingPlatformBuilderHook Boilerplate Pattern
Analysis of commit 372c5f1
Summary
Detected 10+ nearly identical
TestingPlatformBuilderHookclasses across Platform extensions. Each class follows the same boilerplate pattern with only minor variations (namespace, method call, XML documentation). This represents significant structural duplication that increases maintenance burden and violates DRY principles.Duplication Details
Pattern: TestingPlatformBuilderHook Boilerplate
Severity: High
Occurrences: 10 instances
Total Lines: ~206 lines of mostly duplicated code
Locations:
src/Platform/Microsoft.Testing.Extensions.TrxReport/TestingPlatformBuilderHook.cssrc/Platform/Microsoft.Testing.Extensions.AzureFoundry/TestingPlatformBuilderHook.cssrc/Platform/Microsoft.Testing.Extensions.Retry/TestingPlatformBuilderHook.cssrc/Platform/Microsoft.Testing.Extensions.Telemetry/TestingPlatformBuilderHook.cssrc/Platform/Microsoft.Testing.Extensions.CrashDump/TestingPlatformBuilderHook.cssrc/Platform/Microsoft.Testing.Extensions.AzureDevOpsReport/TestingPlatformBuilderHook.cssrc/Platform/Microsoft.Testing.Extensions.MSBuild/TestingPlatformBuilderHook.cssrc/Platform/Microsoft.Testing.Extensions.HangDump/TestingPlatformBuilderHook.cssrc/Platform/Microsoft.Testing.Extensions.HotReload/TestingPlatformBuilderHook.cssrc/Platform/Microsoft.Testing.Extensions.HtmlReport/TestingPlatformBuilderHook.csCode Sample (TrxReport):
Code Sample (HangDump - with attribute variation):
Impact Analysis
Refactoring Recommendations
Option 1: Source Generator (Recommended)
Create a Roslyn source generator that auto-generates
TestingPlatformBuilderHookclasses based on assembly-level attributes:Benefits:
Estimated effort: 8-12 hours
Option 2: Convention-Based Reflection
Use reflection in
TestingPlatformAutoRegisteredExtensionsto discover and invoke extension methods by convention:Benefits:
Drawbacks:
Estimated effort: 4-6 hours
Option 3: Base Class with Template Method
Create an abstract base with virtual methods:
Benefits:
Drawbacks:
Estimated effort: 2-3 hours
Implementation Checklist
Analysis Metadata
Add this agentic workflows to your repo
To install this agentic workflow, run