using Microsoft.Extensions.Options; using NeonSprawl.Server.Game.Items; using NeonSprawl.Server.Game.Skills; namespace NeonSprawl.Server.Game.Crafting; /// DI registration for the fail-fast recipe catalog (NEO-66) and recipe definition registry (NEO-67). public static class RecipeCatalogServiceCollectionExtensions { /// Binds and registers and as singletons. public static IServiceCollection AddRecipeDefinitionCatalog(this IServiceCollection services, IConfiguration configuration) { services.AddOptions() .Bind(configuration.GetSection(ContentPathsOptions.SectionName)); services.AddSingleton(sp => { var hostEnv = sp.GetRequiredService(); var opts = sp.GetRequiredService>().Value; var itemCatalog = sp.GetRequiredService(); var skillCatalog = sp.GetRequiredService(); var logger = sp.GetRequiredService() .CreateLogger("NeonSprawl.Server.Game.Crafting.RecipeCatalog"); var recipesDir = RecipeCatalogPathResolution.ResolveRecipesDirectory( opts.RecipesDirectory, hostEnv.ContentRootPath); var recipeDefSchemaPath = RecipeCatalogPathResolution.ResolveRecipeDefSchemaPath( recipesDir, opts.RecipeDefSchemaPath, hostEnv.ContentRootPath); var recipeIoRowSchemaPath = RecipeCatalogPathResolution.ResolveRecipeIoRowSchemaPath( recipesDir, opts.RecipeIoRowSchemaPath, hostEnv.ContentRootPath); var knownItemIds = itemCatalog.ById.Keys.ToHashSet(StringComparer.Ordinal); var knownSkillIds = skillCatalog.ById.Keys.ToHashSet(StringComparer.Ordinal); return RecipeDefinitionCatalogLoader.Load( recipesDir, recipeDefSchemaPath, recipeIoRowSchemaPath, knownItemIds, knownSkillIds, logger); }); services.AddSingleton(sp => new RecipeDefinitionRegistry(sp.GetRequiredService())); return services; } }