From ed12902bf4232db5650b55f12616602e9f88b713 Mon Sep 17 00:00:00 2001 From: AlxndrVgt Date: Fri, 23 Jan 2026 10:59:02 +0100 Subject: [PATCH 1/3] feat: make reports template based --- src/BafDbContext.cs | 2 - src/Reports/Abstractions/IReport.cs | 9 ++ src/Reports/Abstractions/IReportService.cs | 7 ++ src/Reports/Abstractions/IReportWithKey.cs | 6 -- .../Configurations/ReportConfiguration.cs | 42 -------- src/Reports/Models/Report.cs | 72 ++++--------- src/Reports/ReportsModule.cs | 8 +- src/Reports/Services/ReportService.cs | 101 +++++++----------- .../Services/HandlebarsTemplateService.cs | 9 +- src/Template/Services/TemplateService.cs | 2 +- 10 files changed, 90 insertions(+), 168 deletions(-) create mode 100644 src/Reports/Abstractions/IReport.cs create mode 100644 src/Reports/Abstractions/IReportService.cs delete mode 100644 src/Reports/Abstractions/IReportWithKey.cs delete mode 100644 src/Reports/Configurations/ReportConfiguration.cs diff --git a/src/BafDbContext.cs b/src/BafDbContext.cs index bac38c4..974dc9b 100644 --- a/src/BafDbContext.cs +++ b/src/BafDbContext.cs @@ -3,7 +3,6 @@ using Avolutions.Baf.Core.Jobs.Models; using Avolutions.Baf.Core.NumberSequences.Models; using Avolutions.Baf.Core.Persistence.Extensions; -using Avolutions.Baf.Core.Reports.Models; using Avolutions.Baf.Core.Settings.Models; using Avolutions.Baf.Core.Setup.Models; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; @@ -29,7 +28,6 @@ public class BafDbContext : IdentityDbContext public DbSet AuditLogs => Set(); public DbSet JobRuns => Set(); public DbSet NumberSequences => Set(); - public DbSet Reports => Set(); public DbSet Settings => Set(); public DbSet SetupStatus => Set(); diff --git a/src/Reports/Abstractions/IReport.cs b/src/Reports/Abstractions/IReport.cs new file mode 100644 index 0000000..72ed047 --- /dev/null +++ b/src/Reports/Abstractions/IReport.cs @@ -0,0 +1,9 @@ +namespace Avolutions.Baf.Core.Reports.Abstractions; + +public interface IReport +{ + string ContentTemplatePath { get; } + string? HeaderTemplatePath { get; } + string? FooterTemplatePath { get; } + Task BuildModelAsync(IReportArgs args, CancellationToken ct = default); +} \ No newline at end of file diff --git a/src/Reports/Abstractions/IReportService.cs b/src/Reports/Abstractions/IReportService.cs new file mode 100644 index 0000000..119d70b --- /dev/null +++ b/src/Reports/Abstractions/IReportService.cs @@ -0,0 +1,7 @@ +namespace Avolutions.Baf.Core.Reports.Abstractions; + +public interface IReportService +{ + Task RenderPdfAsync(IReportArgs args, CancellationToken ct = default) + where TReport : class, IReport; +} \ No newline at end of file diff --git a/src/Reports/Abstractions/IReportWithKey.cs b/src/Reports/Abstractions/IReportWithKey.cs deleted file mode 100644 index f0322db..0000000 --- a/src/Reports/Abstractions/IReportWithKey.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Avolutions.Baf.Core.Reports.Abstractions; - -public interface IReportWithKey -{ - static abstract string ReportKey { get; } -} \ No newline at end of file diff --git a/src/Reports/Configurations/ReportConfiguration.cs b/src/Reports/Configurations/ReportConfiguration.cs deleted file mode 100644 index 85a1c3b..0000000 --- a/src/Reports/Configurations/ReportConfiguration.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Reflection; -using Avolutions.Baf.Core.Reports.Abstractions; -using Avolutions.Baf.Core.Reports.Models; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace Avolutions.Baf.Core.Reports.Configurations; - -public class ReportConfiguration : IEntityTypeConfiguration -{ - public void Configure(EntityTypeBuilder builder) - { - builder.HasIndex(a => a.Key) - .IsUnique(); - - builder.Property(a => a.Key) - .HasMaxLength(128); - - builder.Property(x => x.Json) - .HasColumnType("jsonb"); - - var discriminator = builder.HasDiscriminator(nameof(Report.Key)); - - // Scan all loaded assemblies for concrete Report types - foreach (var type in AppDomain.CurrentDomain.GetAssemblies() - .SelectMany(a => a.GetTypes()) - .Where(t => typeof(Report).IsAssignableFrom(t) - && !t.IsAbstract - && typeof(IReportWithKey).IsAssignableFrom(t))) - { - var prop = type.GetProperty(nameof(IReportWithKey.ReportKey), BindingFlags.Public | BindingFlags.Static); - if (prop != null && prop.PropertyType == typeof(string)) - { - var key = (string?)prop.GetValue(null); - if (!string.IsNullOrWhiteSpace(key)) - { - discriminator.HasValue(type, key); - } - } - } - } -} \ No newline at end of file diff --git a/src/Reports/Models/Report.cs b/src/Reports/Models/Report.cs index 3ad1076..6821c81 100644 --- a/src/Reports/Models/Report.cs +++ b/src/Reports/Models/Report.cs @@ -1,61 +1,35 @@ -using System.ComponentModel.DataAnnotations.Schema; -using Avolutions.Baf.Core.Entity.Models; -using Avolutions.Baf.Core.Reports.Abstractions; -using Microsoft.EntityFrameworkCore; +using Avolutions.Baf.Core.Reports.Abstractions; namespace Avolutions.Baf.Core.Reports.Models; -public abstract class Report : EntityBase +public abstract class Report : IReport + where TModel : IReportModel + where TArgs : IReportArgs { - public string Key { get; set; } = string.Empty; - public string Json { get; set; } = string.Empty; - public string HeaderHtml { get; set; } = string.Empty; - public string ContentHtml { get; set; } = string.Empty; - public string FooterHtml { get; set; } = string.Empty; + private string? _basePath; - // For tooling / reflection - public abstract Type ModelType { get; } - public abstract Type ArgsType { get; } + private string BasePath => _basePath ??= GetBasePath(); - public abstract Task BuildModelAsync( - DbContext db, IReportArgs? args, CancellationToken ct); - - public abstract Task BuildDemoAsync( - DbContext db, CancellationToken ct); -} - -public abstract class Report : Report - where TModel : class, IReportModel, new() - where TArgs : class, IReportArgs, new() -{ - [NotMapped] - public TModel? Model { get; private set; } - - public sealed override Type ModelType => typeof(TModel); - public sealed override Type ArgsType => typeof(TArgs); - - protected abstract Task BuildTypedModelAsync( - DbContext db, TArgs args, CancellationToken ct); - - protected abstract Task BuildTypedDemoAsync( - DbContext db, CancellationToken ct); - - public sealed override async Task BuildModelAsync( - DbContext db, IReportArgs? args, CancellationToken ct) + private string GetBasePath() { - if (args is not TArgs typed) + var ns = GetType().Namespace?.Replace(".", "/") ?? ""; + var index = ns.IndexOf('/'); + if (index > 0) { - throw new ArgumentException( - $"Report args must be of type {typeof(TArgs).Name}. " + - $"Received {args?.GetType().Name ?? "null"}.", nameof(args)); + ns = ns[(index + 1)..]; } - - return await BuildTypedModelAsync(db, typed, ct).ContinueWith(t => t.Result, ct); + + return Path.Combine(AppContext.BaseDirectory, ns, "Templates"); } - public sealed override async Task BuildDemoAsync( - DbContext db, CancellationToken ct) - { - return await BuildTypedDemoAsync(db, ct); - } + protected string TemplatePath(string fileName) => Path.Combine(BasePath, fileName); + + public abstract string ContentTemplatePath { get; } + public virtual string? HeaderTemplatePath => null; + public virtual string? FooterTemplatePath => null; + + public abstract Task BuildModelAsync(TArgs args, CancellationToken ct = default); + + async Task IReport.BuildModelAsync(IReportArgs args, CancellationToken ct) + => await BuildModelAsync((TArgs)args, ct); } \ No newline at end of file diff --git a/src/Reports/ReportsModule.cs b/src/Reports/ReportsModule.cs index c9fa5e8..612f185 100644 --- a/src/Reports/ReportsModule.cs +++ b/src/Reports/ReportsModule.cs @@ -1,6 +1,5 @@ -using Avolutions.Baf.Core.Entity.Abstractions; -using Avolutions.Baf.Core.Module.Abstractions; -using Avolutions.Baf.Core.Reports.Models; +using Avolutions.Baf.Core.Module.Abstractions; +using Avolutions.Baf.Core.Reports.Abstractions; using Avolutions.Baf.Core.Reports.Services; using Microsoft.Extensions.DependencyInjection; @@ -10,7 +9,6 @@ public class ReportsModule : IFeatureModule { public void Register(IServiceCollection services) { - services.AddScoped(); - services.AddScoped, ReportService>(); + services.AddScoped(); } } \ No newline at end of file diff --git a/src/Reports/Services/ReportService.cs b/src/Reports/Services/ReportService.cs index 74dd186..ef069bd 100644 --- a/src/Reports/Services/ReportService.cs +++ b/src/Reports/Services/ReportService.cs @@ -1,77 +1,34 @@ -using Avolutions.Baf.Core.Entity.Services; -using Avolutions.Baf.Core.Reports.Abstractions; -using Avolutions.Baf.Core.Reports.Models; +using Avolutions.Baf.Core.Reports.Abstractions; using Avolutions.Baf.Core.Template.Services; -using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Playwright; -using NJsonSchema; -using NJsonSchema.Generation; namespace Avolutions.Baf.Core.Reports.Services; -public class ReportService : EntityService +public class ReportService : IReportService { + private readonly IServiceProvider _serviceProvider; private readonly HandlebarsTemplateService _templateService; - public ReportService(DbContext context, HandlebarsTemplateService templateService) : base(context) + public ReportService(IServiceProvider serviceProvider, HandlebarsTemplateService templateService) { _templateService = templateService; - } - - public async Task GetByKeyAsync(string key, CancellationToken ct = default) - { - var report = await DbSet.FirstOrDefaultAsync(t => t.Key == key, ct); - if (report == null) - { - throw new InvalidOperationException($"Report with key '{key}' not found."); - } - - return report; - } - - public async Task GetModelSchemaJsonAsync(string key, CancellationToken ct = default) - { - var report = await GetByKeyAsync(key, ct); - var settings = new SystemTextJsonSchemaGeneratorSettings - { - FlattenInheritanceHierarchy = true - }; - var schema = JsonSchema.FromType(report.ModelType, settings); - - return schema.ToJson(); - } - - public async Task BuildModelAsync(Report report, IReportArgs? args, CancellationToken ct = default) - { - return await report.BuildModelAsync(Context, args, ct); + _serviceProvider = serviceProvider; } - public async Task BuildDemoAsync(Report report, CancellationToken ct = default) + public async Task RenderPdfAsync(IReportArgs args, CancellationToken ct = default) + where TReport : class, IReport { - return await report.BuildDemoAsync(Context, ct); - } - - public async Task RenderPdfAsync(string reportKey, IReportModel model, CancellationToken ct = default) - { - var report = await GetByKeyAsync(reportKey, ct); - return await RenderPdfAsync(report, model, ct); - } - - public async Task RenderPdfAsync(string reportKey, IReportArgs? args, CancellationToken ct = default) - { - var report = await GetByKeyAsync(reportKey, ct); - var model = await BuildModelAsync(report, args, ct); + var report = ActivatorUtilities.CreateInstance(_serviceProvider); + var model = await report.BuildModelAsync(args, ct); - return await RenderPdfAsync(report, model, ct); - } - - public async Task RenderPdfAsync(Report report, IReportModel model, CancellationToken ct = default) - { - ct.ThrowIfCancellationRequested(); - - var contentHtml = await _templateService.ApplyModelToTemplateAsync(report.ContentHtml, model, ct); - var headerHtml = await _templateService.ApplyModelToTemplateAsync(report.HeaderHtml, model, ct); - var footerHtml = await _templateService.ApplyModelToTemplateAsync(report.FooterHtml, model, ct); + var contentHtml = await RenderTemplateAsync(report.ContentTemplatePath, model, ct); + var headerHtml = report.HeaderTemplatePath != null + ? await RenderTemplateAsync(report.HeaderTemplatePath, model, ct) + : ""; + var footerHtml = report.FooterTemplatePath != null + ? await RenderTemplateAsync(report.FooterTemplatePath, model, ct) + : ""; using var playwright = await Playwright.CreateAsync(); await using var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions @@ -88,9 +45,31 @@ public async Task RenderPdfAsync(Report report, IReportModel model, Canc PrintBackground = true, DisplayHeaderFooter = true, HeaderTemplate = headerHtml, - FooterTemplate = footerHtml + FooterTemplate = footerHtml, + Margin = new Margin + { + Top = "30mm", + Bottom = "30mm", + Left = "10mm", + Right = "10mm" + } }); return pdf; } + + private async Task RenderTemplateAsync(string templatePath, IReportModel model, CancellationToken ct) + { + var fullPath = Path.IsPathRooted(templatePath) + ? templatePath + : Path.Combine(AppContext.BaseDirectory, templatePath); + + if (!File.Exists(fullPath)) + { + throw new FileNotFoundException($"Template not found: {fullPath}", fullPath); + } + + var template = await File.ReadAllTextAsync(fullPath, ct); + return await _templateService.ApplyModelToTemplateAsync(template, model, ct); + } } \ No newline at end of file diff --git a/src/Template/Services/HandlebarsTemplateService.cs b/src/Template/Services/HandlebarsTemplateService.cs index 9cfcfd4..75b7c9d 100644 --- a/src/Template/Services/HandlebarsTemplateService.cs +++ b/src/Template/Services/HandlebarsTemplateService.cs @@ -9,10 +9,15 @@ public override IReadOnlyList ExtractFieldNames(Stream template) throw new NotImplementedException(); } - public override Task ApplyValuesToTemplateAsync(string template, IDictionary values, CancellationToken ct) + public override Task ApplyModelToTemplateAsync(string template, object model, CancellationToken ct = default) { var compiledTemplate = Handlebars.Compile(template); - var result = compiledTemplate(values); + var result = compiledTemplate(model); return Task.FromResult(result); } + + public override Task ApplyValuesToTemplateAsync(string template, IDictionary values, CancellationToken ct) + { + throw new NotImplementedException(); + } } \ No newline at end of file diff --git a/src/Template/Services/TemplateService.cs b/src/Template/Services/TemplateService.cs index ae6740d..f72935c 100644 --- a/src/Template/Services/TemplateService.cs +++ b/src/Template/Services/TemplateService.cs @@ -6,7 +6,7 @@ namespace Avolutions.Baf.Core.Template.Services; public abstract class TemplateService : ITemplateService { - public Task ApplyModelToTemplateAsync(TTemplate template, object model, CancellationToken ct = default) + public virtual Task ApplyModelToTemplateAsync(TTemplate template, object model, CancellationToken ct = default) { ArgumentNullException.ThrowIfNull(template); ArgumentNullException.ThrowIfNull(model); From 03bbe5791efb2c8a102864046c2252dd17c0b817 Mon Sep 17 00:00:00 2001 From: AlxndrVgt Date: Tue, 24 Feb 2026 19:42:17 +0100 Subject: [PATCH 2/3] feat: add db context factory --- src/Audit/AuditModule.cs | 3 ++- src/Entity/EntityModule.cs | 3 ++- .../Extensions/ServiceCollectionExtensions.cs | 1 + src/Jobs/Infrastructure/JobService.cs | 1 + src/Jobs/Infrastructure/JobWorker.cs | 1 + .../Extensions/ServiceCollectionExtensions.cs | 12 +++++++++++- .../Services/NumberSequenceService.cs | 1 + src/{ => Persistence}/BafDbContext.cs | 2 +- src/Persistence/BafDbContextFactoryWrapper.cs | 19 +++++++++++++++++++ src/Settings/Infrastructure/SettingsStore.cs | 1 + src/Setup/Services/SetupService.cs | 3 ++- 11 files changed, 42 insertions(+), 5 deletions(-) rename src/{ => Persistence}/BafDbContext.cs (97%) create mode 100644 src/Persistence/BafDbContextFactoryWrapper.cs diff --git a/src/Audit/AuditModule.cs b/src/Audit/AuditModule.cs index cede015..82dc035 100644 --- a/src/Audit/AuditModule.cs +++ b/src/Audit/AuditModule.cs @@ -3,6 +3,7 @@ using Avolutions.Baf.Core.Audit.Services; using Avolutions.Baf.Core.Module.Abstractions; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; namespace Avolutions.Baf.Core.Audit; @@ -11,6 +12,6 @@ public class AuditModule : IFeatureModule public void Register(IServiceCollection services) { services.AddScoped(typeof(IAuditLogService<>), typeof(AuditLogService<>)); - services.AddScoped(); + services.TryAddSingleton(); } } \ No newline at end of file diff --git a/src/Entity/EntityModule.cs b/src/Entity/EntityModule.cs index e1c0f37..3505126 100644 --- a/src/Entity/EntityModule.cs +++ b/src/Entity/EntityModule.cs @@ -3,6 +3,7 @@ using Avolutions.Baf.Core.Entity.Services; using Avolutions.Baf.Core.Module.Abstractions; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; namespace Avolutions.Baf.Core.Entity; @@ -11,7 +12,7 @@ public class EntityModule : IFeatureModule public void Register(IServiceCollection services) { services.AddScoped(typeof(IEntityService<>), typeof(EntityService<>)); - services.AddScoped(); + services.TryAddSingleton(); services.AddSingleton(typeof(IEntityRouteProvider<>), typeof(EntityRouteProvider<>)); } } \ No newline at end of file diff --git a/src/Identity/Extensions/ServiceCollectionExtensions.cs b/src/Identity/Extensions/ServiceCollectionExtensions.cs index aeb2480..8749a97 100644 --- a/src/Identity/Extensions/ServiceCollectionExtensions.cs +++ b/src/Identity/Extensions/ServiceCollectionExtensions.cs @@ -1,5 +1,6 @@ using Avolutions.Baf.Core.Identity.Models; using Avolutions.Baf.Core.Identity.Services; +using Avolutions.Baf.Core.Persistence; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.DependencyInjection; diff --git a/src/Jobs/Infrastructure/JobService.cs b/src/Jobs/Infrastructure/JobService.cs index 587b777..8345aca 100644 --- a/src/Jobs/Infrastructure/JobService.cs +++ b/src/Jobs/Infrastructure/JobService.cs @@ -3,6 +3,7 @@ using Avolutions.Baf.Core.Identity.Models; using Avolutions.Baf.Core.Jobs.Abstractions; using Avolutions.Baf.Core.Jobs.Models; +using Avolutions.Baf.Core.Persistence; using Microsoft.EntityFrameworkCore; namespace Avolutions.Baf.Core.Jobs.Infrastructure; diff --git a/src/Jobs/Infrastructure/JobWorker.cs b/src/Jobs/Infrastructure/JobWorker.cs index 7d33418..6564a99 100644 --- a/src/Jobs/Infrastructure/JobWorker.cs +++ b/src/Jobs/Infrastructure/JobWorker.cs @@ -2,6 +2,7 @@ using System.Threading.Channels; using Avolutions.Baf.Core.Jobs.Abstractions; using Avolutions.Baf.Core.Jobs.Models; +using Avolutions.Baf.Core.Persistence; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; diff --git a/src/Module/Extensions/ServiceCollectionExtensions.cs b/src/Module/Extensions/ServiceCollectionExtensions.cs index 10236b5..5b69bc3 100644 --- a/src/Module/Extensions/ServiceCollectionExtensions.cs +++ b/src/Module/Extensions/ServiceCollectionExtensions.cs @@ -3,6 +3,7 @@ using Avolutions.Baf.Core.Entity.Interceptors; using Avolutions.Baf.Core.Lookups.Interceptors; using Avolutions.Baf.Core.Module.Abstractions; +using Avolutions.Baf.Core.Persistence; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -33,6 +34,15 @@ public static class ServiceCollectionExtensions public static IServiceCollection AddBafCore(this IServiceCollection services, params Assembly[] assemblies) where TContext : BafDbContext { + // Register a factory alias so framework services (e.g., EntityService) can depend on + // IDbContextFactory without knowing the concrete context type. + // This is the factory equivalent of the scoped DbContext alias below. + services.TryAddScoped>(sp => + new BafDbContextFactoryWrapper(sp.GetRequiredService>())); + + // Keep scoped aliases for backward compatibility. + // AddDbContextFactory already registers TContext as scoped, so API controllers + // and other non-Blazor code that injects DbContext/BafDbContext directly still works. services.TryAddScoped(sp => sp.GetRequiredService()); services.TryAddScoped(sp => sp.GetRequiredService()); @@ -48,7 +58,7 @@ public static IServiceCollection AddBafCore(this IServiceCollection se services.AddSingleton(new BafRegistry(modules, moduleAssemblies)); // Add database context interceptors - services.AddDbContext((sp, options) => + services.AddDbContextFactory((sp, options) => { options.AddInterceptors( sp.GetRequiredService(), diff --git a/src/NumberSequences/Services/NumberSequenceService.cs b/src/NumberSequences/Services/NumberSequenceService.cs index 1bad3b2..49ba5cb 100644 --- a/src/NumberSequences/Services/NumberSequenceService.cs +++ b/src/NumberSequences/Services/NumberSequenceService.cs @@ -1,4 +1,5 @@ using Avolutions.Baf.Core.NumberSequences.Models; +using Avolutions.Baf.Core.Persistence; using Microsoft.EntityFrameworkCore; namespace Avolutions.Baf.Core.NumberSequences.Services; diff --git a/src/BafDbContext.cs b/src/Persistence/BafDbContext.cs similarity index 97% rename from src/BafDbContext.cs rename to src/Persistence/BafDbContext.cs index 974dc9b..7f4ddb6 100644 --- a/src/BafDbContext.cs +++ b/src/Persistence/BafDbContext.cs @@ -9,7 +9,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; -namespace Avolutions.Baf.Core; +namespace Avolutions.Baf.Core.Persistence; /// /// Base DbContext for the BAF framework. diff --git a/src/Persistence/BafDbContextFactoryWrapper.cs b/src/Persistence/BafDbContextFactoryWrapper.cs new file mode 100644 index 0000000..3c2df24 --- /dev/null +++ b/src/Persistence/BafDbContextFactoryWrapper.cs @@ -0,0 +1,19 @@ +using Microsoft.EntityFrameworkCore; + +namespace Avolutions.Baf.Core.Persistence; + +internal class BafDbContextFactoryWrapper : IDbContextFactory + where TContext : BafDbContext +{ + private readonly IDbContextFactory _inner; + + public BafDbContextFactoryWrapper(IDbContextFactory inner) + { + _inner = inner; + } + + public BafDbContext CreateDbContext() + { + return _inner.CreateDbContext(); + } +} \ No newline at end of file diff --git a/src/Settings/Infrastructure/SettingsStore.cs b/src/Settings/Infrastructure/SettingsStore.cs index 3bfb0c6..3ba47c5 100644 --- a/src/Settings/Infrastructure/SettingsStore.cs +++ b/src/Settings/Infrastructure/SettingsStore.cs @@ -1,6 +1,7 @@ using System.Collections.Concurrent; using System.Reflection; using System.Text.Json; +using Avolutions.Baf.Core.Persistence; using Avolutions.Baf.Core.Settings.Abstractions; using Avolutions.Baf.Core.Settings.Attributes; using Avolutions.Baf.Core.Settings.Models; diff --git a/src/Setup/Services/SetupService.cs b/src/Setup/Services/SetupService.cs index d0fa7a0..f2755ac 100644 --- a/src/Setup/Services/SetupService.cs +++ b/src/Setup/Services/SetupService.cs @@ -1,4 +1,5 @@ -using Avolutions.Baf.Core.Setup.Infrastructure; +using Avolutions.Baf.Core.Persistence; +using Avolutions.Baf.Core.Setup.Infrastructure; using Avolutions.Baf.Core.Setup.Models; using Microsoft.EntityFrameworkCore; From 1ff3e17a55b1f5c9b2d99542b346510281878050 Mon Sep 17 00:00:00 2001 From: AlxndrVgt Date: Mon, 30 Mar 2026 16:38:11 +0200 Subject: [PATCH 3/3] chore: set version to 0.20.0 --- src/Avolutions.Baf.Core.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Avolutions.Baf.Core.csproj b/src/Avolutions.Baf.Core.csproj index fd7dd71..ba9ba02 100644 --- a/src/Avolutions.Baf.Core.csproj +++ b/src/Avolutions.Baf.Core.csproj @@ -6,7 +6,7 @@ enable Avolutions.Baf.Core - 0.19.0 + 0.20.0 Avolutions BAF Core Avolutions