From 70349f37f04aa993448d9a8e1f94c9891f1777ed Mon Sep 17 00:00:00 2001 From: Mike Christensen Date: Fri, 28 Aug 2026 12:31:34 -0700 Subject: [PATCH] Modernize dependencies and split ASP.NET integration --- .github/dependabot.yml | 15 ++++++ .github/workflows/build.yml | 16 ++++-- .github/workflows/publish.yml | 26 ++++++++-- Directory.Build.props | 7 +++ README.md | 25 ++++++++-- src/Core.AspNetCore/Core.AspNetCore.csproj | 32 ++++++++++++ .../KPCMiddleware.cs | 22 ++++---- src/Core/Context/DBContext.cs | 11 +++- src/Core/Context/DBContextBuilder.cs | 7 +++ src/Core/Context/IKPCContext.cs | 2 + src/Core/Context/StaticContext.cs | 4 ++ src/Core/Context/StaticContextBuilder.cs | 7 +++ src/Core/Context/StaticIngredientLoader.cs | 2 +- src/Core/Core.csproj | 13 ++--- src/Core/Modeler/DBSnapshot.cs | 31 ++++++------ src/Core/Modeler/ModelingSession.cs | 9 ++-- src/Core/NLP/DefaultTracer.cs | 50 +++++++++---------- src/Core/NLP/Parser.cs | 2 - src/Core/NLP/SynonymTree.cs | 2 +- src/Core/NLP/Tokens/StaticToken.cs | 10 +++- src/DB/DB.csproj | 23 +++------ src/DB/DatabaseAdapter.cs | 9 +++- src/DB/DatabaseAdapterBuilder.cs | 7 +++ src/DB/DatabaseExporter.cs | 49 ++++++++++-------- src/DB/DatabaseImporter.cs | 49 ++++++++++-------- src/DB/EnumMapper.cs | 2 +- src/DB/NLP/IngredientLoader.cs | 2 +- src/UnitTests/DBContextCapabilities.cs | 6 +-- src/UnitTests/Mock/MockContext.cs | 3 ++ src/UnitTests/Modeler.cs | 13 +++-- src/UnitTests/UnitTests.csproj | 10 ++-- src/core.slnx | 3 ++ 32 files changed, 306 insertions(+), 163 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 Directory.Build.props create mode 100644 src/Core.AspNetCore/Core.AspNetCore.csproj rename src/{Core/Middleware => Core.AspNetCore}/KPCMiddleware.cs (50%) diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..99b7926 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,15 @@ +version: 2 +updates: + - package-ecosystem: nuget + directory: /src + schedule: + interval: weekly + groups: + nuget-dependencies: + patterns: + - "*" + + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 51663e0..5f07b1f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,7 +28,9 @@ jobs: - name: Set up .NET uses: actions/setup-dotnet@v5 with: - dotnet-version: 10.0.x + dotnet-version: | + 8.0.x + 10.0.x - name: Restore dependencies run: dotnet restore src/core.slnx @@ -49,7 +51,15 @@ jobs: --configuration Release --no-build --output artifacts - -p:PackageVersion=1.0.0-ci.${{ github.run_number }} + -p:Version=2.0.0-ci.${{ github.run_number }} + + - name: Pack ASP.NET Core integration + run: >- + dotnet pack src/Core.AspNetCore/Core.AspNetCore.csproj + --configuration Release + --no-build + --output artifacts + -p:Version=2.0.0-ci.${{ github.run_number }} - name: Pack DB run: >- @@ -57,7 +67,7 @@ jobs: --configuration Release --no-build --output artifacts - -p:PackageVersion=1.0.0-ci.${{ github.run_number }} + -p:Version=2.0.0-ci.${{ github.run_number }} - name: Upload packages uses: actions/upload-artifact@v7 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c0c5b9f..bcb2ed9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -15,7 +15,7 @@ env: jobs: publish: - name: Publish Core and DB + name: Publish KitchenPC packages runs-on: ubuntu-latest environment: nuget @@ -37,7 +37,9 @@ jobs: - name: Set up .NET uses: actions/setup-dotnet@v5 with: - dotnet-version: 10.0.x + dotnet-version: | + 8.0.x + 10.0.x - name: Restore dependencies run: dotnet restore src/core.slnx @@ -58,7 +60,7 @@ jobs: --configuration Release --no-build --output artifacts - -p:PackageVersion=${{ steps.version.outputs.value }} + -p:Version=${{ steps.version.outputs.value }} - name: Pack DB run: >- @@ -66,7 +68,15 @@ jobs: --configuration Release --no-build --output artifacts - -p:PackageVersion=${{ steps.version.outputs.value }} + -p:Version=${{ steps.version.outputs.value }} + + - name: Pack ASP.NET Core integration + run: >- + dotnet pack src/Core.AspNetCore/Core.AspNetCore.csproj + --configuration Release + --no-build + --output artifacts + -p:Version=${{ steps.version.outputs.value }} - name: Upload release packages uses: actions/upload-artifact@v7 @@ -96,3 +106,11 @@ jobs: --api-key ${{ steps.nuget-login.outputs.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate + + - name: Publish ASP.NET Core integration to NuGet + run: >- + dotnet nuget push + artifacts/KitchenPC.Core.AspNetCore.${{ steps.version.outputs.value }}.nupkg + --api-key ${{ steps.nuget-login.outputs.NUGET_API_KEY }} + --source https://api.nuget.org/v3/index.json + --skip-duplicate diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..6c87c4a --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,7 @@ + + + true + all + $(WarningsAsErrors);NU1901;NU1902;NU1903;NU1904 + + diff --git a/README.md b/README.md index 5557acf..87e891c 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Example applications and a small static data snapshot are available in the Building and Testing ==== -Install the .NET 10 SDK, then restore, build, and test from the repository root: +Install the .NET 8 and .NET 10 SDKs, then restore, build, and test from the repository root: ```bash dotnet restore src/core.slnx @@ -37,7 +37,20 @@ dotnet build src/core.slnx --configuration Release --no-restore dotnet test src/UnitTests/UnitTests.csproj --configuration Release --no-build --no-restore ``` -The build includes `KitchenPC.Core`, `KitchenPC.DB`, and the unit tests. +The build includes `KitchenPC.Core`, `KitchenPC.DB`, `KitchenPC.Core.AspNetCore`, and the unit tests. + +`KitchenPC.Core` contains the engine and static context. Add `KitchenPC.DB` when using PostgreSQL, +and add `KitchenPC.Core.AspNetCore` only when registering a context with ASP.NET Core dependency +injection. Applications can connect KitchenPC to standard Microsoft logging through either context +builder: + +```csharp +var context = DBContext.Configure + .Logging(loggerFactory) + .Adapter(/* database adapter configuration */) + .Identity(() => AuthIdentity.Anonymous) + .Create(); +``` Database Schema Naming ==== @@ -80,11 +93,13 @@ sample-data startup and memory measurements. Packages and Releases ==== -Every push and pull request builds and tests the solution, then creates matching prerelease packages for CI validation. Version tags publish `KitchenPC.Core` and `KitchenPC.DB` to NuGet with the same version. For example: +Every push and pull request builds and tests the solution, then creates matching prerelease packages +for CI validation. Version tags publish `KitchenPC.Core`, `KitchenPC.DB`, and +`KitchenPC.Core.AspNetCore` to NuGet with the same version. For example: ```bash -git tag -a v1.0.0 -m "KitchenPC 1.0.0" -git push origin v1.0.0 +git tag -a v2.0.0 -m "KitchenPC 2.0.0" +git push origin v2.0.0 ``` NuGet package versions are immutable. Always increment the version for a subsequent release. diff --git a/src/Core.AspNetCore/Core.AspNetCore.csproj b/src/Core.AspNetCore/Core.AspNetCore.csproj new file mode 100644 index 0000000..2d71603 --- /dev/null +++ b/src/Core.AspNetCore/Core.AspNetCore.csproj @@ -0,0 +1,32 @@ + + + net8.0;net10.0 + KitchenPC.Core.AspNetCore + KitchenPC.Core + ASP.NET Core integration for the KitchenPC recipe engine + Mike Christensen + KitchenPC + KitchenPC.Core.AspNetCore + 2.0.0 + https://github.com/KitchenPC/core + https://github.com/KitchenPC/core.git + git + MIT + README.md + false + recipes;aspnetcore;dependency-injection + true + true + true + snupkg + true + $(NoWarn);1591 + + + + + + + + + diff --git a/src/Core/Middleware/KPCMiddleware.cs b/src/Core.AspNetCore/KPCMiddleware.cs similarity index 50% rename from src/Core/Middleware/KPCMiddleware.cs rename to src/Core.AspNetCore/KPCMiddleware.cs index d51d39a..dd3f941 100644 --- a/src/Core/Middleware/KPCMiddleware.cs +++ b/src/Core.AspNetCore/KPCMiddleware.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Security.Claims; using KitchenPC.Core.Context; using Microsoft.AspNetCore.Http; @@ -8,33 +8,31 @@ namespace KitchenPC.Core.Middleware; public static class KPCMiddleware { - /// - /// Adds KitchenPC OWIN Middleware components into Service Collection - /// - /// - /// + /// Adds a configured KitchenPC context to an ASP.NET Core service collection. public static void AddKPCContext( this IServiceCollection services, IConfiguration configuration ) where T : class, IKPCContext { + ArgumentNullException.ThrowIfNull(services); + ArgumentNullException.ThrowIfNull(configuration); + var kpcContext = configuration.InitializeContext(); services.AddHttpContextAccessor(); services.AddScoped(ctx => { - IHttpContextAccessor contextAccessor = ctx.GetService(); + var contextAccessor = ctx.GetService(); if (contextAccessor?.HttpContext?.User?.Identity?.IsAuthenticated == true) { - string id = contextAccessor.HttpContext.User.FindFirst(ClaimTypes.Sid)?.Value; - string alias = contextAccessor.HttpContext.User.FindFirst(ClaimTypes.Name)?.Value; + var id = contextAccessor.HttpContext.User.FindFirst(ClaimTypes.Sid)?.Value; + var alias = contextAccessor.HttpContext.User.FindFirst(ClaimTypes.Name)?.Value; - if (Guid.TryParse(id, out Guid guidId) && !string.IsNullOrWhiteSpace(alias)) + if (Guid.TryParse(id, out var guidId) && !string.IsNullOrWhiteSpace(alias)) { - var identity = new AuthIdentity(guidId, alias); - return kpcContext.AsUserContext(identity) as T; + return kpcContext.AsUserContext(new AuthIdentity(guidId, alias)) as T; } } diff --git a/src/Core/Context/DBContext.cs b/src/Core/Context/DBContext.cs index 34e6628..6e82ae2 100644 --- a/src/Core/Context/DBContext.cs +++ b/src/Core/Context/DBContext.cs @@ -11,6 +11,8 @@ using KitchenPC.Core.Provisioning; using KitchenPC.Core.Recipes; using KitchenPC.Core.ShoppingLists; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using IngredientUsage = KitchenPC.Core.Ingredients.IngredientUsage; namespace KitchenPC.Core.Context; @@ -31,7 +33,8 @@ private AsUser( Parser parser, IDBAdapter adapter, AuthIdentity identity, - DBContextCapabilities capabilities + DBContextCapabilities capabilities, + ILoggerFactory loggerFactory ) { this.ingParser = ingParser; @@ -41,6 +44,7 @@ DBContextCapabilities capabilities this.Identity = identity; this.GetIdentity = () => identity; this.Capabilities = capabilities; + this.LoggerFactory = loggerFactory; } public static AsUser Clone(DBContext context, AuthIdentity identity) => @@ -50,7 +54,8 @@ public static AsUser Clone(DBContext context, AuthIdentity identity) => context.parser, context.Adapter, identity, - context.Capabilities + context.Capabilities, + context.LoggerFactory ); } @@ -63,6 +68,7 @@ public static AsUser Clone(DBContext context, AuthIdentity identity) => /// Gets the optional in-memory capabilities configured for this context. public DBContextCapabilities Capabilities { get; internal set; } = DBContextCapabilities.All; + public ILoggerFactory LoggerFactory { get; internal set; } = NullLoggerFactory.Instance; /// Gets or sets the IDBAdapter used to directly talk with the database. public IDBAdapter Adapter { get; set; } @@ -166,6 +172,7 @@ public virtual void Initialize() if (HasCapability(DBContextCapabilities.IngredientParsing)) { + NlpTracer.SetTracer(new DefaultTracer(LoggerFactory)); IngredientSynonyms.InitIndex(Adapter.IngredientLoader); UnitSynonyms.InitIndex(Adapter.UnitLoader); FormSynonyms.InitIndex(Adapter.FormLoader); diff --git a/src/Core/Context/DBContextBuilder.cs b/src/Core/Context/DBContextBuilder.cs index ea8c137..1733ba3 100644 --- a/src/Core/Context/DBContextBuilder.cs +++ b/src/Core/Context/DBContextBuilder.cs @@ -1,4 +1,5 @@ using System; +using Microsoft.Extensions.Logging; namespace KitchenPC.Core.Context; @@ -24,6 +25,12 @@ public DBContextBuilder Identity(Func getIdentity) return this; } + public DBContextBuilder Logging(ILoggerFactory loggerFactory) + { + context.LoggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); + return this; + } + /// /// Selects the optional in-memory indexes initialized by this context. All capabilities are /// enabled by default for backward compatibility. diff --git a/src/Core/Context/IKPCContext.cs b/src/Core/Context/IKPCContext.cs index fb1c6b4..31e24f9 100644 --- a/src/Core/Context/IKPCContext.cs +++ b/src/Core/Context/IKPCContext.cs @@ -9,6 +9,7 @@ using KitchenPC.Core.NLP; using KitchenPC.Core.Recipes; using KitchenPC.Core.ShoppingLists; +using Microsoft.Extensions.Logging; using IngredientUsage = KitchenPC.Core.Ingredients.IngredientUsage; namespace KitchenPC.Core.Context; @@ -18,6 +19,7 @@ public interface IKPCContext { void Initialize(); AuthIdentity Identity { get; } + ILoggerFactory LoggerFactory { get; } // Autocomplete support IEnumerable AutocompleteIngredient(string query); diff --git a/src/Core/Context/StaticContext.cs b/src/Core/Context/StaticContext.cs index 806e751..97a7301 100644 --- a/src/Core/Context/StaticContext.cs +++ b/src/Core/Context/StaticContext.cs @@ -15,6 +15,8 @@ using KitchenPC.Core.Provisioning.DTO; using KitchenPC.Core.Recipes; using KitchenPC.Core.ShoppingLists; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using IngredientUsage = KitchenPC.Core.Ingredients.IngredientUsage; namespace KitchenPC.Core.Context; @@ -27,6 +29,7 @@ public class StaticContext : IKPCContext, IProvisionTarget, IProvisionSource public Func GetIdentity { get; set; } public Parser Parser { get; private set; } public ModelerProxy ModelerProxy { get; private set; } + public ILoggerFactory LoggerFactory { get; internal set; } = NullLoggerFactory.Instance; private DataStore store; private IngredientParser ingParser; @@ -51,6 +54,7 @@ private StaticContext() /// public void Initialize() { + NlpTracer.SetTracer(new DefaultTracer(LoggerFactory)); var file = CompressedStore ? "KPCData.gz" : "KPCData.xml"; var path = Path.Combine(DataDirectory, file); // TODO Fix logging diff --git a/src/Core/Context/StaticContextBuilder.cs b/src/Core/Context/StaticContextBuilder.cs index 113c386..7ab23d0 100644 --- a/src/Core/Context/StaticContextBuilder.cs +++ b/src/Core/Context/StaticContextBuilder.cs @@ -1,4 +1,5 @@ using System; +using Microsoft.Extensions.Logging; namespace KitchenPC.Core.Context; @@ -34,5 +35,11 @@ public StaticContextBuilder Identity(Func getIdentity) return this; } + public StaticContextBuilder Logging(ILoggerFactory loggerFactory) + { + context.LoggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); + return this; + } + public StaticContext Create() => context; } diff --git a/src/Core/Context/StaticIngredientLoader.cs b/src/Core/Context/StaticIngredientLoader.cs index 2fc669b..fe10b01 100644 --- a/src/Core/Context/StaticIngredientLoader.cs +++ b/src/Core/Context/StaticIngredientLoader.cs @@ -84,7 +84,7 @@ public StaticIngredientLoader(DataStore store) if (nodes.ContainsKey(ingId)) { - Parser.Log.ErrorFormat( + NlpTracer.Trace(TraceLevel.Error, "[NLP Loader] Duplicate ingredient key due to bad DB data: {0} ({1})", name, ingId diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index 6c6fc01..6570905 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -1,6 +1,6 @@  - netstandard2.0 + net8.0;net10.0 default true $(NoWarn);1591 @@ -12,7 +12,7 @@ bin\$(Configuration)\ Mike Christensen KitchenPC.Core - 1.0.0 + 2.0.0 https://github.com/KitchenPC/core https://github.com/KitchenPC/core.git git @@ -31,13 +31,6 @@ - - - - - + diff --git a/src/Core/Modeler/DBSnapshot.cs b/src/Core/Modeler/DBSnapshot.cs index d4108ff..8814835 100644 --- a/src/Core/Modeler/DBSnapshot.cs +++ b/src/Core/Modeler/DBSnapshot.cs @@ -4,6 +4,7 @@ using System.Linq; using KitchenPC.Core.Context; using KitchenPC.Core.Recipes; +using Microsoft.Extensions.Logging; namespace KitchenPC.Core.Modeler; @@ -52,8 +53,8 @@ public void Index(IKPCContext context) ratingGraph.AddRating(r, uid, rid); } - ModelingSession.Log.InfoFormat( - "Building Rating Graph took {0}ms.", + snapshot.logger.LogInformation( + "Building Rating Graph took {ElapsedMilliseconds}ms.", timer.ElapsedMilliseconds ); timer.Reset(); @@ -72,8 +73,8 @@ from o in loader.LoadRecipeGraph() } ).ToDictionary(k => k.RecipeId); - ModelingSession.Log.InfoFormat( - "Building empty RecipeNodes took {0}ms.", + snapshot.logger.LogInformation( + "Building empty RecipeNodes took {ElapsedMilliseconds}ms.", timer.ElapsedMilliseconds ); timer.Reset(); @@ -108,8 +109,8 @@ from o in loader.LoadRecipeGraph() } } - ModelingSession.Log.InfoFormat( - "Indexing recipes by tag took {0}ms.", + snapshot.logger.LogInformation( + "Indexing recipes by tag took {ElapsedMilliseconds}ms.", timer.ElapsedMilliseconds ); timer.Reset(); @@ -173,8 +174,8 @@ from o in loader.LoadRecipeGraph() ); } - ModelingSession.Log.InfoFormat( - "Creating IngredientUsage vertices took {0}ms.", + snapshot.logger.LogInformation( + "Creating IngredientUsage vertices took {ElapsedMilliseconds}ms.", timer.ElapsedMilliseconds ); timer.Reset(); @@ -189,8 +190,8 @@ select snapshot.recipeMap[s] ).ToArray(); } - ModelingSession.Log.InfoFormat( - "Building suggestions for each recipe took {0}ms.", + snapshot.logger.LogInformation( + "Building suggestions for each recipe took {ElapsedMilliseconds}ms.", timer.ElapsedMilliseconds ); timer.Reset(); @@ -233,8 +234,8 @@ public void Dispose() GC.Collect(); //Force garbage collection now, since there might be several hundred megs of unreachable allocations timer.Stop(); - ModelingSession.Log.InfoFormat( - "Cleaning up Indexer took {0}ms.", + snapshot.logger.LogInformation( + "Cleaning up Indexer took {ElapsedMilliseconds}ms.", timer.ElapsedMilliseconds ); } @@ -243,6 +244,7 @@ public void Dispose() public sealed partial class DBSnapshot { + private readonly ILogger logger; private Dictionary recipeMap; //Recipe Index (will include hidden recipes) private Dictionary ingredientMap; //Ingredient Index private IEnumerable[] recipeList; //Ordinal recipe index keyed by tag (for picking random recipes) @@ -254,6 +256,7 @@ public int RecipeCount public DBSnapshot(IKPCContext context) { + logger = context.LoggerFactory.CreateLogger(); var timer = new Stopwatch(); timer.Start(); @@ -263,8 +266,8 @@ public DBSnapshot(IKPCContext context) } timer.Stop(); - ModelingSession.Log.InfoFormat( - "Total time building snapshot was {0}ms.", + logger.LogInformation( + "Total time building snapshot was {ElapsedMilliseconds}ms.", timer.ElapsedMilliseconds ); } diff --git a/src/Core/Modeler/ModelingSession.cs b/src/Core/Modeler/ModelingSession.cs index 5db201d..0598e3c 100644 --- a/src/Core/Modeler/ModelingSession.cs +++ b/src/Core/Modeler/ModelingSession.cs @@ -4,7 +4,7 @@ using System.Linq; using KitchenPC.Core.Context; using KitchenPC.Core.Recipes; -using log4net; +using Microsoft.Extensions.Logging; namespace KitchenPC.Core.Modeler { @@ -36,7 +36,7 @@ public class ModelingSession private readonly DBSnapshot db; private readonly IKPCContext context; private readonly IUserProfile profile; - public static ILog Log = LogManager.GetLogger(typeof(ModelingSession)); + private readonly ILogger logger; /// /// Create a ModelingSession instance. @@ -49,6 +49,7 @@ public ModelingSession(IKPCContext context, DBSnapshot db, IUserProfile profile) this.db = db; this.context = context; this.profile = profile; + this.logger = context.LoggerFactory.CreateLogger(); this.favTags = new bool[RecipeTag.NUM_TAGS]; this.favIngs = new int[profile.FavoriteIngredients.Length]; @@ -190,8 +191,8 @@ public Model Generate(int recipes, byte scale) } timer.Stop(); - Log.InfoFormat( - "Generating set of {0} recipes took {1}ms.", + logger.LogInformation( + "Generating set of {RecipeCount} recipes took {ElapsedMilliseconds}ms.", recipes, timer.ElapsedMilliseconds ); diff --git a/src/Core/NLP/DefaultTracer.cs b/src/Core/NLP/DefaultTracer.cs index 96217ce..6ba3a3b 100644 --- a/src/Core/NLP/DefaultTracer.cs +++ b/src/Core/NLP/DefaultTracer.cs @@ -1,37 +1,35 @@ -using log4net; +using System; +using System.Globalization; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; namespace KitchenPC.Core.NLP; -/// Implementation of ITracer that uses Log4Net +/// Implementation of ITracer that uses Microsoft.Extensions.Logging. public class DefaultTracer : ITracer { - private readonly ILog log; + private readonly ILogger log; - public DefaultTracer() - { - log = LogManager.GetLogger(typeof(Parser)); - log.Info("Initialized logger for new NLP parser."); - } + public DefaultTracer() : this(NullLoggerFactory.Instance) { } + + public DefaultTracer(ILoggerFactory loggerFactory) => + log = (loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory))) + .CreateLogger(); public void Trace(TraceLevel level, string message, params object[] args) { - switch (level) - { - case TraceLevel.Debug: - log.DebugFormat(message, args); - break; - case TraceLevel.Error: - log.ErrorFormat(message, args); - break; - case TraceLevel.Fatal: - log.FatalFormat(message, args); - break; - case TraceLevel.Info: - log.InfoFormat(message, args); - break; - case TraceLevel.Warn: - log.WarnFormat(message, args); - break; - } + var formattedMessage = string.Format(CultureInfo.InvariantCulture, message, args); + log.Log(MapLevel(level), "{Message}", formattedMessage); } + + private static LogLevel MapLevel(TraceLevel level) => + level switch + { + TraceLevel.Debug => LogLevel.Debug, + TraceLevel.Error => LogLevel.Error, + TraceLevel.Fatal => LogLevel.Critical, + TraceLevel.Info => LogLevel.Information, + TraceLevel.Warn => LogLevel.Warning, + _ => LogLevel.None, + }; } diff --git a/src/Core/NLP/Parser.cs b/src/Core/NLP/Parser.cs index a79bc4e..6c7618a 100644 --- a/src/Core/NLP/Parser.cs +++ b/src/Core/NLP/Parser.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; -using log4net; namespace KitchenPC.Core.NLP; @@ -13,7 +12,6 @@ public class Parser private List