Feature Request: Interface-Based Architecture for Static Classes
Problem
Currently, the DotNet static partial class and other command classes are not easily testable or mockable in unit tests. The static nature makes dependency injection and testing scenarios challenging.
Proposed Solution
Expose static classes like public static partial class DotNet as interfaces with the current static implementations serving as default implementations.
Current Architecture
DotNet uses static partial class pattern across 20+ files
- Each method returns fluent builders (e.g.,
DotNetRunBuilder)
- Builders call static
CommandExtensions.Run() method
- No dependency injection support
Proposed Interface Design
public interface IDotNet
{
DotNetRunBuilder Run();
DotNetBuildBuilder Build();
DotNetBuildBuilder Build(string project);
// ... all other command methods
}
public interface ICommandRunner
{
CommandResult Run(string executable, params string[] arguments);
CommandResult Run(string executable, string[] arguments, CommandOptions options);
}
public class DotNetService : IDotNet
{
public DotNetRunBuilder Run() => DotNet.Run();
public DotNetBuildBuilder Build() => DotNet.Build();
// Delegates to existing static methods
}
Implementation Requirements
- Backward Compatibility: Zero breaking changes to existing API
- Builder Integration: Update builders to use injected
ICommandRunner
- DI Support: Extension methods for
IServiceCollection registration
- Testing: Enable full mockability for unit tests
Benefits
- Testability: Mock CLI operations in unit tests
- Dependency Injection: First-class DI container support
- Custom Implementations: Environment-specific behavior (local vs CI)
- Maintainability: Cleaner separation of concerns
Usage Examples
// Static approach (unchanged)
await DotNet.Build().WithConfiguration("Release").GetStringAsync();
// Interface-based approach (new)
await dotNetService.Build().WithConfiguration("Release").GetStringAsync();
// Testing with mocks
var mockRunner = new Mock<ICommandRunner>();
var dotNetService = new DotNetService(mockRunner.Object);
Implementation Plan
- Create core interfaces (
IDotNet, ICommandRunner)
- Create default implementations wrapping existing statics
- Update builder classes for dependency injection
- Add DI registration extensions
- Comprehensive testing with mocked implementations
This would enable both usage patterns while maintaining full backward compatibility.
Feature Request: Interface-Based Architecture for Static Classes
Problem
Currently, the
DotNetstatic partial class and other command classes are not easily testable or mockable in unit tests. The static nature makes dependency injection and testing scenarios challenging.Proposed Solution
Expose static classes like
public static partial class DotNetas interfaces with the current static implementations serving as default implementations.Current Architecture
DotNetuses static partial class pattern across 20+ filesDotNetRunBuilder)CommandExtensions.Run()methodProposed Interface Design
Implementation Requirements
ICommandRunnerIServiceCollectionregistrationBenefits
Usage Examples
Implementation Plan
IDotNet,ICommandRunner)This would enable both usage patterns while maintaining full backward compatibility.