Files
Anvil/Anvil/Hosting/SelfTestRegistrationHostedService.cs
T
JonKazama-Hellion 90803bcd3c feat(bootstrap): wire DI host, hosted services, and plugin entry
The plugin is now loadable. Dalamud injects five services into the Plugin
constructor (Lightless pattern), the constructor builds the generic-host
container synchronously, and PluginLifecycle drives StartAsync from
LoadAsync. Module 02+ extends PluginHostFactory; this file set stays put.

- PluginHostDependencies (record): bundles the five Dalamud services
  v0.1.0 needs (IDalamudPluginInterface, IPluginLog, IDataManager,
  IFramework, ISelfTestRegistry).
- PluginHostFactory.Build: HostBuilder + AddDalamudLogging + the four
  service blocks (Dalamud services, Anvil singletons, ISelfTestStep
  collection, IHostedService init chain). Every registration uses an
  explicit factory lambda - the default activator only sees public
  ctors and Anvil follows the internal-sealed convention.
- PluginLifecycle (IAsyncDisposable): owns Host.StartAsync, marshals the
  Host.Dispose call onto the framework thread, idempotency guard via
  Interlocked, ExceptionDispatchInfo.Capture preserves the original
  load-throw stack when a failure cascades.
- Plugin (IAsyncDalamudPlugin): constructor injection of the five
  Dalamud services, builds the dependencies record, kicks off the host
  build, hands DisposeAsync to the lifecycle.
- Hosting/RecipeDataLoadHostedService: dispatches LuminaRecipeAdapter
  .LoadInternal onto the framework thread on StartAsync. Lumina sheet
  reads have no documented thread safety; conservative default.
- Hosting/SelfTestRegistrationHostedService: collects every
  ISelfTestStep registration from DI and hands them to
  ISelfTestRegistry.RegisterTestSteps once the host is up.
- SelfTest/RecipeDataAdapterLoadStep: nine pass criteria per spec §4.1
  (IsLoaded, RecipeCount > 0, ActionCount in 30..80, BuffsByKind.Count
  == 14, ConditionsByKind.Count == 11, Foods >= 30, Medicines >= 5,
  BasicSynthesis.RowIdByClassJob[8] == 100001, Cosmic-surface
  silent-degradation warning). Returns Waiting while the catalog is
  still loading.
- Infrastructure/Logging trio: DalamudLogger maps
  Microsoft.Extensions.Logging levels to IPluginLog, the provider
  emits an Anvil bootstrap banner with a Forge-Bronze fingerprint on
  ctor, the extension wires the provider into the ILoggingBuilder via
  TryAddEnumerable.
2026-05-27 21:58:38 +02:00

44 lines
1.5 KiB
C#

// IHostedService adapter that hands every registered ISelfTestStep to
// Dalamud's ISelfTestRegistry once the host is up. Resolving the steps
// through DI keeps the plugin entry point free of static Plugin.X
// lookups - the DI container collects each step that was registered as
// IEnumerable<ISelfTestStep>.
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Dalamud.Plugin.SelfTest;
using Dalamud.Plugin.Services;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace Anvil.Hosting;
internal sealed class SelfTestRegistrationHostedService : IHostedService
{
private readonly ISelfTestRegistry _registry;
private readonly IEnumerable<ISelfTestStep> _steps;
private readonly ILogger<SelfTestRegistrationHostedService> _logger;
public SelfTestRegistrationHostedService(
ISelfTestRegistry registry,
IEnumerable<ISelfTestStep> steps,
ILogger<SelfTestRegistrationHostedService> logger
)
{
_registry = registry;
_steps = steps;
_logger = logger;
}
public Task StartAsync(CancellationToken cancellationToken)
{
var stepList = new List<ISelfTestStep>(_steps);
_registry.RegisterTestSteps(stepList);
_logger.LogInformation("Anvil registered {Count} self-test step(s)", stepList.Count);
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}