From 90414bf4873c8e1fb89438d8f38da5735888f1f6 Mon Sep 17 00:00:00 2001 From: Martin Jarvis Date: Fri, 16 Jan 2026 16:18:19 +0000 Subject: [PATCH] refactor: remove duplicate console encoding and service locator pattern Changes: 1. Removed duplicate Console.OutputEncoding/InputEncoding from Application.cs - Encoding is already set in Program.cs bootstrap before DI - Application.cs should use IConsoleService for console operations 2. Replaced Service Locator pattern with constructor injection - Inject IEnvironmentService directly instead of via IServiceProvider - Application now receives all dependencies through constructor - Improves testability and follows DI best practices Refs: #129 Co-Authored-By: Claude Opus 4.5 --- .../Application.cs | 18 ++++----------- .../ProgramTests.cs | 23 +++++++------------ 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/src/McjCoderOrg.ClaudeAutoResume/Application.cs b/src/McjCoderOrg.ClaudeAutoResume/Application.cs index d605f36..eebc16a 100644 --- a/src/McjCoderOrg.ClaudeAutoResume/Application.cs +++ b/src/McjCoderOrg.ClaudeAutoResume/Application.cs @@ -5,8 +5,6 @@ using McjCoderOrg.ClaudeAutoResume.Resources; using McjCoderOrg.ClaudeAutoResume.Services; -using Microsoft.Extensions.DependencyInjection; - using Serilog; namespace McjCoderOrg.ClaudeAutoResume; @@ -22,7 +20,7 @@ internal sealed class Application : IApplication private readonly IArgumentParser _argumentParser; private readonly IConsoleService _console; - private readonly IServiceProvider _serviceProvider; + private readonly IEnvironmentService _environment; private readonly ILogger _logger; /// @@ -30,26 +28,23 @@ internal sealed class Application : IApplication /// /// The argument parser. /// The console service. - /// The service provider for creating monitors. + /// The environment service. /// The logger. public Application( IArgumentParser argumentParser, IConsoleService console, - IServiceProvider serviceProvider, + IEnvironmentService environment, ILogger? logger = null) { _argumentParser = argumentParser; _console = console; - _serviceProvider = serviceProvider; + _environment = environment; _logger = logger ?? Log.Logger; } /// public async Task RunAsync(string[] args) { - Console.OutputEncoding = Encoding.UTF8; - Console.InputEncoding = Encoding.UTF8; - var parseResult = _argumentParser.Parse(args); if (parseResult.ShowHelp) @@ -101,10 +96,7 @@ public async Task RunAsync(string[] args) private ClaudeMonitor CreateMonitor(WrapperConfig config) { - // Create monitor with DI services - var console = _serviceProvider.GetRequiredService(); - var environment = _serviceProvider.GetRequiredService(); - return new ClaudeMonitor(config, console, environment, _logger); + return new ClaudeMonitor(config, _console, _environment, _logger); } private static string? ValidateArguments(ParseResult result) diff --git a/tests/McjCoderOrg.ClaudeAutoResume.Tests/ProgramTests.cs b/tests/McjCoderOrg.ClaudeAutoResume.Tests/ProgramTests.cs index 730799e..eb2c2a5 100644 --- a/tests/McjCoderOrg.ClaudeAutoResume.Tests/ProgramTests.cs +++ b/tests/McjCoderOrg.ClaudeAutoResume.Tests/ProgramTests.cs @@ -10,36 +10,29 @@ public sealed class ProgramTests { private readonly ITestOutputHelper _output; private readonly Mock _mockConsole; - private readonly Mock _mockServiceProvider; + private readonly Mock _mockEnvironment; private Application _app = null!; public ProgramTests(ITestOutputHelper output) { _output = output; _mockConsole = new Mock(MockBehavior.Loose); - _mockServiceProvider = new Mock(MockBehavior.Loose); + _mockEnvironment = new Mock(MockBehavior.Loose); // Setup console mock _mockConsole.Setup(c => c.WindowWidth).Returns(120); _mockConsole.Setup(c => c.WindowHeight).Returns(30); + + // Setup environment mock + _mockEnvironment.Setup(e => e.CurrentDirectory).Returns(Environment.CurrentDirectory); + _mockEnvironment.Setup(e => e.GetEnvironmentVariables()).Returns(new Dictionary(StringComparer.Ordinal)); } private Application CreateApplication(Mock? parserMock = null) { - var mockEnvironment = new Mock(MockBehavior.Loose); - mockEnvironment.Setup(e => e.CurrentDirectory).Returns(Environment.CurrentDirectory); - mockEnvironment.Setup(e => e.GetEnvironmentVariables()).Returns(new Dictionary(StringComparer.Ordinal)); - - var parser = parserMock?.Object ?? new ArgumentParser(mockEnvironment.Object); - - _mockServiceProvider - .Setup(sp => sp.GetService(typeof(IConsoleService))) - .Returns(_mockConsole.Object); - _mockServiceProvider - .Setup(sp => sp.GetService(typeof(IEnvironmentService))) - .Returns(mockEnvironment.Object); + var parser = parserMock?.Object ?? new ArgumentParser(_mockEnvironment.Object); - return new Application(parser, _mockConsole.Object, _mockServiceProvider.Object); + return new Application(parser, _mockConsole.Object, _mockEnvironment.Object); } [Fact]