refactor(di): migrate Root + Misc to ILogger<T> (DI-4 Slice D)

Slice D shrinks vs the original plan: three of the six files cannot
take an ILogger ctor arg without breaking external contracts.

Migrated (8 LogProxy sites across 4 files):
- Commands: 2 sites (Warning, Error). New ctor takes ILogger<Commands>.
- Themes/ThemeRegistry: 1 site (Debug). ILogger<ThemeRegistry>? is
  optional (default null) so the existing Build-Suite tests that
  construct `new ThemeRegistry()` parameterless keep working without
  changes. _logger?.LogDebug guards the call site.
- PayloadHandler: 3 sites (Error, Warning, Error). New ctor takes
  ILogger<PayloadHandler>. ChatLogWindow's two `new PayloadHandler(this)`
  sites (the direct field and the Lender lambda) now hand a fresh
  CreateLogger<PayloadHandler>() from the existing _loggerFactory.

Not migrated (5 sites stay on Plugin.LogProxy, plan drifts D12-D14):
- D12 - Configuration (1 site): IPluginConfiguration, instantiated by
  Dalamud's Interface.GetPluginConfig() via reflection on the
  parameterless ctor. Adding an ILogger arg would break GetPluginConfig.
- D13 - Message (4 sites): partial data class with two ctor overloads,
  mass-instantiated across 3 plugin sites plus Newtonsoft JSON
  deserialisation. Ctor extension would be invasive across ~20 call
  sites with low payoff (data-class logger is unusual).
- D14 - FontManager (2 sites): both Plugin.LogProxy calls live in
  static methods (TryGetHellionFontBytes, AddFontWithFallback) that
  cannot reach an instance _logger. Same root cause as D8 in
  GameFunctions. FontManager joins the static-bucket alongside
  EmoteCache et al.; the ctor + _logger field added mid-Slice-D were
  rolled back to keep the class clean.

Plugin.LogProxy surface after C9 (8 file buckets, ~12 sites total):
- 4 originally-static consumers: EmoteCache, AutoTranslate,
  MemoryUtil, WrapperUtil
- 3 cannot-take-ctor-arg consumers: Configuration, Message, FontManager
- 1 single-static-method consumer: GameFunctions.TryOpenAdventurerPlate
  (D8 from Slice B)

Smoke 2 is now due.
This commit is contained in:
2026-05-17 11:02:08 +02:00
parent c955f30422
commit 54ff88d6d4
6 changed files with 42 additions and 13 deletions
+6 -2
View File
@@ -1,9 +1,12 @@
using HellionChat.Themes.Builtin;
using Microsoft.Extensions.Logging;
namespace HellionChat.Themes;
public sealed class ThemeRegistry
{
private readonly ILogger<ThemeRegistry>? _logger;
public const string DefaultSlug = HellionArctic.Slug;
// 1Hz throttle for the v1.4.8 B2 auto-refresh-on-active path. The
@@ -29,8 +32,9 @@ public sealed class ThemeRegistry
private long _lastActiveStampCheckMs = -ActiveStampPollIntervalMs;
private DateTime _lastActiveStamp = DateTime.MinValue;
public ThemeRegistry(string? customThemesDir = null)
public ThemeRegistry(string? customThemesDir = null, ILogger<ThemeRegistry>? logger = null)
{
_logger = logger;
// Insertion order drives the Theme-Picker grid layout (3 columns).
// Row 1: blue family. Row 2: purple to magenta family.
// Row 3: green / warm / classic. Row 4: Synthwave Sunset as a
@@ -206,7 +210,7 @@ public sealed class ThemeRegistry
catch (Exception ex) when (IsRecoverableFileLock(ex))
{
// Editor mid-save: keep last known good, retry on next refresh.
Plugin.LogProxy.Debug(
_logger?.LogDebug(
$"Custom theme {Path.GetFileName(path)} is locked, keeping last known good"
);
if (cached.Theme is not null)