15 KiB
DataPRO Improvement Opportunities
Status: Analysis Complete
Date: 2026-04-17
Analysis Scope: Architecture, Stability, Performance
Methodology
Items ranked by Effort vs. Impact matrix. priority is triage order (1 = most urgent).
-
Low Effort: < 1 week
-
Medium Effort: 1-3 weeks
-
High Effort: 3+ weeks
-
High Impact: Major architectural improvement, significantly improves stability/performance/testability
-
Medium Impact: Noticeable improvement but not critical
-
Low Impact: Minor cleanup, nice to have
Immediate Priority (Triage 1-5)
#1. Refactor RunTestVariables to Injectables (Low Effort, High Impact)
Category: State Management
Problem:
RunTestVariables.csis anabstract classwith 40+ static properties- Located in two locations (
Common/DTS.Common/Enums/andCommon/DTS.CommonCore/Enums/) - Creates hidden dependencies throughout codebase
- Difficult to test, impossible to mock
- Lines 287-294 show redundancy:
TOMExcitationWarmupTimeMS = TOM_EXCITATIONWARMUPTIME_MS;(static field initialized from const)
Solution:
- Create
IRunTestVariablesinterface - Implement concrete
RunTestVariablesServiceclass - Register with Unity DI container as singleton
- Inject into consumers instead of static access
- Consolidate to single definition (remove
Common/DTS.CommonCore/Enums/RunTestVariables.cs)
Effort: Low (3-5 days)
Impact: High
Risks:
- Breaking change across 40+ usages (grep shows widespread use in App.xaml.cs, services, ViewModels)
- Mitigation: Step-by-step refactoring with compiler-guided updates
Related Files:
/Users/noise/Code/BRANCH_MAINT_4_04/Common/DTS.Common/Enums/RunTestVariables.cs:1-315/Users/noise/Code/BRANCH_MAINT_4_04/Common/DTS.CommonCore/Enums/RunTestVariables.cs
#2. Create IDbAPI Interface (Low Effort, High Impact)
Category: Database Layer
Problem:
DbAPI.cs:237-373exposes 15+ static properties (Connections, Database, DAS, Sensors, etc.)- No interface abstraction (
IDbAPIdoesn't exist) - Lines 229-240 show
_instancesingleton pattern with static wrappers - Tight coupling: ALL modules depend on static DbAPI, making testing nearly impossible
- Violates Dependency Inversion Principle
Solution:
- Create
IDbAPIinterface with all current static property getters - Implement
DbApiServiceclass that wraps singleton instance - Register with Unity:
container.RegisterType<IDbAPI, DbApiService>(new ContainerControlledLifetimeManager()) - Gradually refactor modules to inject
IDbAPIinstead of staticDbAPI.XXX
Effort: Low (5-7 days)
Impact: High
Risks:
- Massive refactoring (15+ properties used across 40+ modules)
- Mitigation: Keep static wrappers during transition, deprecate gradually
Related Files:
/Users/noise/Code/BRANCH_MAINT_4_04/DataPRO/DbAPI/DbAPI.cs:229-373
#3. Extract Test State Management from App.xaml.cs (Medium Effort, High Impact)
Category: Architecture / God Class Refactoring
Problem:
App.xaml.cs:128-235containsStartTest()andEndTest()methods with 150+ lines each- Mixed concerns: licensing (line 307), DB initialization (line 328), test state (lines 128-235), UI operations
- Lines 103, 119 show static
RunTestVariablesmodifications alongside UI thread marshaling - God class (4620 lines total, only first 500 read but structure evident)
Solution:
- Extract
ITestStateServicewith methods:StartTest(TestConfiguration config)EndTest()SetRunTestRealtimeVariables()
- Extract
ILicensingService(lines 300-340) - Extract
IDatabaseInitializer(lines 328-400) - Register services with Unity, inject into App.xaml.cs
Effort: Medium (2-3 weeks)
Impact: High
Risks:
- Disrupts architectural foundation
- Mitigation: Incremental extraction, keep backward compatibility
Related Files:
/Users/noise/Code/BRANCH_MAINT_4_04/DataPRO/DataPRO/App.xaml.cs:1-4620
#4. Add Unit Test Scaffolding (Low Effort, High Impact)
Category: Testing
Problem:
- Only database tests exist in
DataPRO/UnitTest/ - No ViewModel tests (MVVM pattern but untested)
- No service layer tests
- Lines 22-30 of Architecture.md note "Limited test coverage"
Solution:
- Create test project structure:
DataPRO.Tests.ViewModels/DataPRO.Tests.Services/DataPRO.Tests.Modules/
- Add NUnit/Xunit + Moq setup
- Write 5-10 high-value tests for critical paths:
RunTestVariablesServiceinitializationTestStateService.StartTest()flow- Database connection pooling
Effort: Low (1 week)
Impact: High
Risks:
- Low risk, high reward
Mitigation: Start small, expand coverage iteratively
#5. Fix Async Context in App.xaml.cs (Medium Effort, High Impact)
Category: Threading / Stability
Problem:
- Lines 128-161
StartTest()callsDbOperations.LogDBCaching(),SetRunTestRealtimeVariables()on UI thread - Line 459:
TabPageSource.GetGroups("AllGroups")blocks UI thread for 3-4 seconds - Line 399-406: Database initialization on UI thread during startup
- No async/await pattern anywhere (Architecture.md line 380 notes "BackgroundWorker instead of async/await")
- Lines 238-242, 254-262, 266-274 show Dispatcher marshaling boilerplate
Solution:
- Convert sync DB calls to async:
public async Task StartTestAsync() { await LoadTestConfigurationAsync(); await InitializeDatabaseAsync(); uiContext.Send(_ => RaiseTestStarted(), null); } - Replace
BackgroundWorkerwith async/await throughout codebase - Use
IHostBuilderfor background services
Effort: Medium (2-3 weeks)
Impact: High
Risks:
- Breaking changes to synchronous call chains
- Mitigation: Async-avoid pattern, add overloads during transition
Medium Priority (Triage 6-12)
#6. Improve DASFactory BlockingCollection Threading (Medium Effort, Medium Impact)
Category: Threading / DASFactory
Problem:
- Line 127 of
DASFactory.cs:private BlockingCollection<Tuple<QueueActions, DeviceHandling>> _queueActionPerDevice; - No visible async consumer pattern (read up to line 139, full file 1712 lines)
- Mixed threading model: UI thread produces, worker threads consume
- Lines 156-160 show
StartMulticastAutoDiscovery()without cancellation support
Solution:
- Implement proper async consumer pattern:
private readonly Channel<(QueueActions, DeviceHandling)> _deviceChannel = Channel.CreateBounded<(QueueActions, DeviceHandling)>(new BoundedChannelOptions(100) { FullMode = BoundedChannelFullMode.Wait }); - Add cancellation tokens to long-running Discovery operations
- Use
IHostedServicefor background device monitoring
Effort: Medium (1-2 weeks)
Impact: Medium
Risks:
- Device discovery timing changes
- Mitigation: Thorough integration testing with actual hardware
#7. Database Connection Pooling Optimization (Low Effort, Medium Impact)
Category: Database / Performance
Problem:
- Lines 108-138 in
DbAPI.cscreate newSqlCommandfor every call - Lines 137, 194:
cmd.Connection.Dispose()on every operation - No connection pooling configuration visible
- Stored procedure version negotiation (lines 34-97) executes during runtime path
Solution:
- Configure SQL Connection Pooling in connection string
- Reuse
SqlCommandobjects where possible - Cache SP version results longer (currently cached per invocation)
- Add connection health checks
Effort: Low (1 week)
Impact: Medium
Risks:
- Low risk
Mitigation: Benchmark before/after
#8. Module Dependency Audit (Medium Effort, Medium Impact)
Category: Architecture
Problem:
- 40+ Prism modules (Architecture.md line 37 notes "30+")
- Lines 68-75 of Architecture.md show module registration chaos
- Mixed initialization:
Initialize()vsRegisterTypes() - Tight coupling between modules (e.g., SensorsList → HardwareList → GroupList)
Solution:
- Audit module dependencies with dependency graph tool
- Create module dependency rules (e.g., "Viewers depend on Services but not vice versa")
- Introduce module-level interfaces (
ISensorsModule,IHardwareModule) - Document module contract boundaries
Effort: Medium (2 weeks)
Impact: Medium
Risks:
- Refactoring module initialization patterns
- Mitigation: Document before/after patterns
#9. Replace Static Abstract RunTestVariables with Instance Pattern (Low Effort, Medium Impact)
Category: State Management
Problem:
RunTestVariables.cs:9:public abstract class RunTestVariableswith static properties- Line 287-294: Redundant pattern
public static int Property = CONSTANT; - Inheritance hierarchy unnecessary for data holder
- Makes DI impossible
Solution:
- Convert to
sealed class RunTestVariables : IRunTestVariables - Use constructor injection for configuration
- Add
Reset()method for test isolation
Effort: Low (3-5 days)
Impact: Medium
Risks:
- Breaking change (100+ usages inferred)
- Mitigation: Same as #1, step-by-step
#10. Consolidate Logging Infrastructure (Medium Effort, Medium Impact)
Category: Architecture
Problem:
- Architecture.md line 380: "Mixed logging - custom APILogger and TextLogger classes"
- Two logger types:
APILogger(custom) andTextLogger(file-based) - Lines 78-82 of App.xaml.cs:
_loggers.Add(new TextLogger(...))mixed withAPILogger.Writer = LogStuff(line 324) - No structured logging, no log levels per module
Solution:
- Adopt Serilog or Microsoft.Extensions.Logging
- Configure per-module log levels
- Structured logging for searchability
- Migration plan: wrapper adapters → direct usage
Effort: Medium (2-3 weeks)
Impact: Medium
Risks:
- Log message formatting changes
- Mitigation: Backward compatible adapter layer
#11. Optimize RunTest Real-time Database Calls (Low Effort, Medium Impact)
Category: Performance
Problem:
- Comment at lines 163-165 of App.xaml.cs: "http://manuscript.dts.local/f/cases/33110/Eliminate-DB-communication-while-in-realtime"
- Prepopulation already done (lines 166-218) but still query
Defaults.GetUserSettingValue*()(lines 169-206) - Lines 452-459 of App.xaml.cs:
SettingsDB.GetAllGlobalValues()blocks startup
Solution:
- Cache all settings in
RunTestVariablesat test start - Add runtime settings change listener (if needed)
- Lazy-load non-critical settings
Effort: Low (5-7 days)
Impact: Medium
Risks:
- Settings changes during test not reflected (acceptable tradeoff)
- Mitigation: Document setting freeze at test start
#12. Add Configuration Validation (Medium Effort, Medium Impact)
Category: Stability
Problem:
- No validation of DB connection strings
- No validation of hardware configuration before test start
- Lines 391-411 of App.xaml.cs: Command line args parsed but minimal validation
- Line 349-358: License validation only checks DB type for license type, not actual DB connectivity
Solution:
- Add
IConfigurationValidatorinterface - Validate:
- Database connectivity before bootstrapper
- Hardware configuration completeness before test start
- User permissions
- Fail fast with helpful error messages
Effort: Medium (1-2 weeks)
Impact: Medium
Risks:
- User workflow changes (earlier failures)
- Mitigation: Clear error messages, rollback options
Low Priority (Triage 13+)
#13. Upgrade .NET Framework to .NET 6/8 (High Effort, High Impact)
Category: Architecture / Modernization
Problem:
- Architecture.md line 316: ".NET Framework 4.8"
- Legacy platform, no long-term support
- Missing modern features (native DI, async-streaming, improved threading)
Effort: High (3-4 months)
Impact: High
Risks:
- Major breaking changes
- Dependency compatibility
- Mitigation: Phased migration, test automation
#14. Add Error Handling Patterns (Medium Effort, Medium Impact)
Category: Stability
Problem:
- Lines 129-133, 186-190 of
DbAPI.cs: Genericcatch (Exception ex)withreturn ErrorCodes.ERROR_UNKNOWN - No structured error handling across modules
- Stack traces lost in translation to error codes
Solution:
- Define error hierarchy:
ApplicationException,DatabaseException,HardwareException - Use
Result<T>pattern instead of out params + error codes - Central error handling with DI
Effort: Medium (2 weeks)
Impact: Medium
Risks:
- Breaking change to API contracts
- Mitigation: Gradual adoption
#15. Build Performance Optimization (Low Effort, Low Impact)
Category: Build / CI
Problem:
- 100+ projects in solution (solution file 440+ lines)
- No indication of parallel builds
- Rebuilds entire solution on any change
Solution:
- Project dependency graph optimization
- Precompiled headers for common libraries
- Incremental builds
Effort: Low (3-5 days)
Impact: Low
Risks:
- Low risk
Mitigation: Measure build times before/after
Summary Matrix
| Triage | # | Effort | Impact | Category |
|---|---|---|---|---|
| 1 | #1 | Low | High | State Management |
| 2 | #2 | Low | High | Database Layer |
| 3 | #3 | Medium | High | Architecture |
| 4 | #4 | Low | High | Testing |
| 5 | #5 | Medium | High | Threading |
| 6 | #6 | Medium | Medium | Threading |
| 7 | #7 | Low | Medium | Database |
| 8 | #8 | Medium | Medium | Architecture |
| 9 | #9 | Low | Medium | State Management |
| 10 | #10 | Medium | Medium | Architecture |
| 11 | #11 | Low | Medium | Performance |
| 12 | #12 | Medium | Medium | Stability |
| 13 | #13 | High | High | Modernization |
| 14 | #14 | Medium | Medium | Stability |
| 15 | #15 | Low | Low | Build |
Recommended Immediate Action Plan
Week 1-2: Quick Wins
- #4: Add Unit Test Scaffolding - Establish test infrastructure, write 5-10 tests
- #1: Refactor RunTestVariables - Create interface, inject into 1-2 modules as proof-of-concept
Week 3-6: High Impact Refactoring
- #2: Create IDbAPI Interface - Replace static DbAPI usage in 5 key modules
- #11: Optimize Real-time DB Calls - Cache remaining settings, measure test initialization time
Month 2-3: Architecture Modernization
- #5: Fix Async Context - Replace BackgroundWorker with async/await in App.xaml.cs
- #3: Extract Test State - Create
ITestStateService, refactor StartTest/EndTest
Notes
- Static DbAPI is the root cause of most testability issues (#1, #2, #3 should be grouped)
- RunTestVariables duplication (two files) suggests merging or clear separation needed
- No CI/CD pipeline visible in codebase - recommend adding GitHub Actions/Azure DevOps
- Architecture.md shows "God Class" concerns already identified in prior analysis (GLM5)
Document generated by Qwen3-Coder-Next analysis agent