Compare commits

...

13 Commits

Author SHA1 Message Date
35b7b1a080 refactor(AddReportBehavior): update to add history record. 2025-11-10 17:05:35 +01:00
67d0980c63 move the behaviours about pdf to pdf dir 2025-11-10 16:46:10 +01:00
c6a99b56a2 add GdPicture packages via nuget 2025-11-10 16:18:42 +01:00
31f5d1f340 add SaveBurnedPdfBehavior to services 2025-11-10 15:29:16 +01:00
a2df5d7691 create SaveBurnedPdfBehavior 2025-11-10 15:13:57 +01:00
f8c586dd31 feat(FinishEnvelopeJob): add PDF burning with concurrency control
- Introduced PDFBurnerParams configuration for concurrency limit.
- Added SemaphoreSlim to handle concurrent PDF burning for envelopes.
- Updated job to call _mediator.BurnPdf for each envelope with error handling.
- Preserved logging of job execution and envelope UUIDs.
2025-11-10 15:01:07 +01:00
8aea3c8301 refactor(BurnPdfCommand): add extension methods for ISender
- Introduce BurnPdfCommandExtensions to simplify sending BurnPdfCommand via ISender
- Enables calling `sender.BurnPdf(envelopeId, cancel)` or `sender.BurnPdf(envelopeUuid, cancel)`
- No changes to the underlying PDF burning logic in BurnPdfCommandHandler
2025-11-10 14:00:21 +01:00
495adb8c31 feat(dependency-injection): add optional usePdfBurner flag to AddServices
- Updated EGConfiguration.AddServices to accept a new `usePdfBurner` boolean parameter.
- Pass `usePdfBurner` through to AddEnvelopeGeneratorServices to enable optional PDF burner functionality.
- Maintains existing behavior when parameter is not provided (default false).
2025-11-10 13:53:26 +01:00
86c0a65540 refactor: add conditional PDFBurner and GdPicture service registration 2025-11-10 13:43:44 +01:00
d2e8f1fc5e refactor: simplify GdPicture license resolution in dependency injection 2025-11-10 13:29:02 +01:00
f8369e350f refactor(BurnPdfCommand): replace manual JSON serialization with ToJson extension
- Replaced `System.Text.Json.JsonSerializer.Serialize(request, Format.Json.ForDiagnostics)`
  with `request.ToJson(Format.Json.ForDiagnostics)` for better readability and consistency.
- No functional changes, purely a code style and maintainability improvement.
2025-11-10 13:01:33 +01:00
b8a2ad97ef refactor(BurnPdfCommand): simplify BurnPdfCommand and improve envelope/document handling
- Updated `BurnPdfCommand` to accept `EnvelopeId` or `EnvelopeUuid` instead of full `EnvelopeQueryBase` and document data.
- Reworked `BurnPdfCommandHandler` to fetch envelope and document from repositories, including proper validations and exceptions.
- Removed direct dependency on `Signature` repository; annotations now retrieved via document elements.
- Added detailed exception handling for missing envelope, document, or byte data.
- Minor namespace and using cleanup.
2025-11-10 12:58:04 +01:00
ffffc2d470 refactor(BurnPdfCommand): update BurnPdfCommand to use EnvelopeQueryBase and enhance request structure
- Replaced record-based BurnPdfCommand with class-based implementation
- Added Envelope property of type EnvelopeQueryBase
- Changed parameters to nullable (Document, InstantJSONList)
- Added ByCronService flag for cron-based PDF burning control
- Updated query logic to use request.Envelope.Id instead of EnvelopeId
- Improved code structure for flexibility and service integration
2025-11-10 09:30:04 +01:00
10 changed files with 204 additions and 126 deletions

View File

@ -9,6 +9,11 @@ namespace EnvelopeGenerator.Application.Common.Configurations;
/// </summary>
public class PDFBurnerParams : ITextStyle
{
/// <summary>
///
/// </summary>
public int ConcurrencyLimit { get; set; } = 5;
/// <summary>
///
/// </summary>

View File

@ -11,6 +11,7 @@ using Microsoft.Extensions.Options;
using QRCoder;
using System.Reflection;
using GdPicture14;
using EnvelopeGenerator.Application.Pdf.Behaviors;
namespace EnvelopeGenerator.Application;
@ -24,9 +25,10 @@ public static class DependencyInjection
/// </summary>
/// <param name="services"></param>
/// <param name="config"></param>
/// <param name="usePdfBurner"></param>
/// <returns></returns>
[Obsolete("Use MediatR")]
public static IServiceCollection AddEnvelopeGeneratorServices(this IServiceCollection services, IConfiguration config)
public static IServiceCollection AddEnvelopeGeneratorServices(this IServiceCollection services, IConfiguration config, bool usePdfBurner = false)
{
//Inject CRUD Service and repositoriesad
services.TryAddScoped<IConfigService, ConfigService>();
@ -50,28 +52,31 @@ public static class DependencyInjection
services.Configure<MailParams>(config.GetSection(nameof(MailParams)));
services.Configure<AuthenticatorParams>(config.GetSection(nameof(AuthenticatorParams)));
services.Configure<TotpSmsParams>(config.GetSection(nameof(TotpSmsParams)));
if (usePdfBurner)
{
services.Configure<PDFBurnerParams>(config.GetSection(nameof(PDFBurnerParams)));
services.AddOptions<GdPictureParams>()
.Configure((GdPictureParams opt, IServiceProvider sp) =>
.Configure((GdPictureParams opt, IServiceProvider provider) =>
{
var licenseKey = "GDPICTURE";
using var scope = sp.CreateScope();
var mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
opt.License = config["GdPictureLicenseKey"]
?? mediator.ReadThirdPartyModuleLicenseAsync(licenseKey).GetAwaiter().GetResult()
?? throw new InvalidOperationException($"License record not found for key: {licenseKey}");
?? provider.GetRequiredService<IMediator>().ReadThirdPartyModuleLicenseAsync("GDPICTURE").GetAwaiter().GetResult()
?? throw new InvalidOperationException($"License record not found for key: {"GDPICTURE"}");
});
services.AddSingleton(provider => {
services.AddSingleton(provider =>
{
var license = provider.GetRequiredService<IOptions<GdPictureParams>>().Value.License;
var licenseManager = new LicenseManager();
licenseManager.RegisterKEY(license);
return licenseManager;
});
services.AddTransient(provider => {
services.AddTransient(provider =>
{
// Ensure LicenseManager is resolved so that its constructor is called
_ = provider.GetRequiredService<LicenseManager>();
return new AnnotationManager();
});
}
services.AddHttpClientService<GtxMessagingParams>(config.GetSection(nameof(GtxMessagingParams)));
services.TryAddSingleton<ISmsSender, GTXSmsSender>();
@ -82,6 +87,7 @@ public static class DependencyInjection
services.AddMediatR(cfg =>
{
cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly());
cfg.AddOpenBehaviors(new Type[] { typeof(AddReportBehavior), typeof(SavePdfBehavior) });
});
// Add memory cache

View File

@ -32,16 +32,23 @@
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="System.Formats.Asn1" Version="8.0.2" />
<PackageReference Include="GdPicture" Version="14.3.19.1" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.5" />
<PackageReference Include="System.Formats.Asn1" Version="9.0.10" />
<PackageReference Include="GdPicture" Version="14.3.19.1" />
<PackageReference Include="GdPicture.runtimes.windows" Version="14.3.19.1" />
<PackageReference Include="GdPicture.runtimes.linux" Version="14.3.19.1" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.5" />
<PackageReference Include="System.Formats.Asn1" Version="9.0.10" />
<PackageReference Include="GdPicture" Version="14.3.19.1" />
<PackageReference Include="GdPicture.runtimes.windows" Version="14.3.19.1" />
<PackageReference Include="GdPicture.runtimes.linux" Version="14.3.19.1" />
</ItemGroup>
<ItemGroup>
@ -49,72 +56,6 @@
<ProjectReference Include="..\EnvelopeGenerator.PdfEditor\EnvelopeGenerator.PdfEditor.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="GdPicture.NET.14">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.dll</HintPath>
</Reference>
<Reference Include="GdPicture.NET.14.barcode.1d.writer">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.barcode.1d.writer.dll</HintPath>
</Reference>
<Reference Include="GdPicture.NET.14.barcode.2d.writer">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.barcode.2d.writer.dll</HintPath>
</Reference>
<Reference Include="GdPicture.NET.14.CAD">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.CAD.dll</HintPath>
</Reference>
<Reference Include="GdPicture.NET.14.CAD.DWG">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.CAD.DWG.dll</HintPath>
</Reference>
<Reference Include="GdPicture.NET.14.Common">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.Common.dll</HintPath>
</Reference>
<Reference Include="GdPicture.NET.14.Document">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.Document.dll</HintPath>
</Reference>
<Reference Include="GdPicture.NET.14.Email">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.Email.dll</HintPath>
</Reference>
<Reference Include="GdPicture.NET.14.HTML">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.HTML.dll</HintPath>
</Reference>
<Reference Include="GdPicture.NET.14.Imaging">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.Imaging.dll</HintPath>
</Reference>
<Reference Include="GdPicture.NET.14.Imaging.Formats">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.Imaging.Formats.dll</HintPath>
</Reference>
<Reference Include="GdPicture.NET.14.Imaging.Formats.Conversion">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.Imaging.Formats.Conversion.dll</HintPath>
</Reference>
<Reference Include="GdPicture.NET.14.Imaging.Rendering">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.Imaging.Rendering.dll</HintPath>
</Reference>
<Reference Include="GdPicture.NET.14.MSOfficeBinary">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.MSOfficeBinary.dll</HintPath>
</Reference>
<Reference Include="GdPicture.NET.14.OpenDocument">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.OpenDocument.dll</HintPath>
</Reference>
<Reference Include="GdPicture.NET.14.OpenXML">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.OpenXML.dll</HintPath>
</Reference>
<Reference Include="GdPicture.NET.14.OpenXML.Templating">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.OpenXML.Templating.dll</HintPath>
</Reference>
<Reference Include="GdPicture.NET.14.PDF">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.PDF.dll</HintPath>
</Reference>
<Reference Include="GdPicture.NET.14.RTF">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.RTF.dll</HintPath>
</Reference>
<Reference Include="GdPicture.NET.14.SVG">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.SVG.dll</HintPath>
</Reference>
<Reference Include="GdPicture.NET.14.wia.gateway">
<HintPath>..\packages\GdPicture.14.3.3\lib\net462\GdPicture.NET.14.wia.gateway.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Update="Resources\Model.Designer.cs">
<DesignTime>True</DesignTime>

View File

@ -34,7 +34,7 @@ public record CreateHistoryCommand : EnvelopeReceiverQueryBase, IRequest<History
/// <summary>
///
/// </summary>
public DateTime AddedWhen { get; } = DateTime.Now;
public DateTime AddedWhen { get; } = DateTime.UtcNow;
/// <summary>
///

View File

@ -0,0 +1,44 @@
using MediatR;
using EnvelopeGenerator.Application.Histories.Commands;
using EnvelopeGenerator.Domain.Constants;
namespace EnvelopeGenerator.Application.Pdf.Behaviors;
/// <summary>
///
/// </summary>
public class AddReportBehavior : IPipelineBehavior<BurnPdfCommand, byte[]>
{
private readonly ISender _sender;
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
public AddReportBehavior(ISender sender)
{
_sender = sender;
}
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="next"></param>
/// <param name="cancel"></param>
/// <returns></returns>
public async Task<byte[]> Handle(BurnPdfCommand request, RequestHandlerDelegate<byte[]> next, CancellationToken cancel)
{
var docResult = await next(cancel);
var base64 = Convert.ToBase64String(docResult);
await _sender.Send(new CreateHistoryCommand()
{
EnvelopeId = request.EnvelopeId,
UserReference = "System",
Status = EnvelopeStatus.EnvelopeReportCreated,
}, cancel);
return docResult;
}
}

View File

@ -0,0 +1,23 @@
using MediatR;
namespace EnvelopeGenerator.Application.Pdf.Behaviors;
/// <summary>
///
/// </summary>
public class SavePdfBehavior : IPipelineBehavior<BurnPdfCommand, byte[]>
{
/// <summary>
///
/// </summary>
/// <param name="request"></param>
/// <param name="next"></param>
/// <param name="cancel"></param>
/// <returns></returns>
public async Task<byte[]> Handle(BurnPdfCommand request, RequestHandlerDelegate<byte[]> next, CancellationToken cancel)
{
var docResult = await next(cancel);
var base64 = Convert.ToBase64String(docResult);
return docResult;
}
}

View File

@ -1,7 +1,9 @@
using DigitalData.Core.Abstraction.Application.Repository;
using DigitalData.Core.Exceptions;
using EnvelopeGenerator.Application.Common.Configurations;
using EnvelopeGenerator.Application.Exceptions;
using EnvelopeGenerator.Application.Common.Dto.PSPDFKitInstant;
using EnvelopeGenerator.Application.Common.Extensions;
using EnvelopeGenerator.Application.Exceptions;
using EnvelopeGenerator.Domain.Constants;
using EnvelopeGenerator.Domain.Entities;
using GdPicture14;
@ -10,14 +12,39 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using EnvelopeGenerator.Application.Common.Extensions;
namespace EnvelopeGenerator.Application.Pdf;
/// <summary>
///
/// </summary>
public record BurnPdfCommand(byte[] Document, List<string> InstantJSONList, int EnvelopeId) : IRequest<byte[]>;
public record BurnPdfCommand(int? EnvelopeId = null, string? EnvelopeUuid = null) : IRequest<byte[]>;
/// <summary>
///
/// </summary>
public static class BurnPdfCommandExtensions
{
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="envelopeId"></param>
/// <param name="cancel"></param>
/// <returns></returns>
public static Task<byte[]> BurnPdf(this ISender sender, int envelopeId, CancellationToken cancel = default)
=> sender.Send(new BurnPdfCommand(EnvelopeId: envelopeId), cancel);
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="envelopeUuid"></param>
/// <param name="cancel"></param>
/// <returns></returns>
public static Task<byte[]> BurnPdf(this ISender sender, string envelopeUuid, CancellationToken cancel = default)
=> sender.Send(new BurnPdfCommand(EnvelopeUuid: envelopeUuid), cancel);
}
/// <summary>
///
@ -28,23 +55,27 @@ public class BurnPdfCommandHandler : IRequestHandler<BurnPdfCommand, byte[]>
private readonly AnnotationManager _manager;
private readonly IRepository<Signature> _signRepo;
private readonly ILogger<BurnPdfCommandHandler> _logger;
private readonly IRepository<Envelope> _envRepo;
private readonly IRepository<Domain.Entities.DocumentStatus> _docStatusRepo;
/// <summary>
///
/// </summary>
/// <param name="pdfBurnerParams"></param>
/// <param name="manager"></param>
/// <param name="signRepo"></param>
/// <param name="logger"></param>
public BurnPdfCommandHandler(IOptions<PDFBurnerParams> pdfBurnerParams, AnnotationManager manager, IRepository<Signature> signRepo, ILogger<BurnPdfCommandHandler> logger)
/// <param name="envRepo"></param>
/// <param name="docStatusRepo"></param>
public BurnPdfCommandHandler(IOptions<PDFBurnerParams> pdfBurnerParams, AnnotationManager manager, ILogger<BurnPdfCommandHandler> logger, IRepository<Envelope> envRepo, IRepository<Domain.Entities.DocumentStatus> docStatusRepo)
{
_options = pdfBurnerParams.Value;
_manager = manager;
_signRepo = signRepo;
_docStatusRepo = docStatusRepo;
_logger = logger;
_envRepo = envRepo;
}
@ -57,15 +88,31 @@ public class BurnPdfCommandHandler : IRequestHandler<BurnPdfCommand, byte[]>
/// <exception cref="NotImplementedException"></exception>
public async Task<byte[]> Handle(BurnPdfCommand request, CancellationToken cancel)
{
// read the elements of envelope with their annotations
var elements = await _signRepo
.Where(sig => sig.Document.EnvelopeId == request.EnvelopeId)
.Include(sig => sig.Annotations)
.ToListAsync(cancel);
var envQuery =
request.EnvelopeId is not null ? _envRepo.Where(env => env.Id == request.EnvelopeId) :
request.EnvelopeUuid is not null ? _envRepo.Where(env => env.Uuid == request.EnvelopeUuid) :
throw new BadRequestException("Request validation failed: Either Envelope Id or Envelope Uuid must be provided.");
return elements.Count > 0
? BurnElementAnnotsToPDF(request.Document, elements)
: BurnInstantJSONAnnotsToPDF(request.Document, request.InstantJSONList);
var envelope = await envQuery
.Include(env => env.Documents!).ThenInclude(doc => doc.Elements!).ThenInclude(element => element.Annotations)
.FirstOrDefaultAsync(cancel)
?? throw new BadRequestException($"Envelope could not be found. Request details:\n" +
request.ToJson(Format.Json.ForDiagnostics));
var doc = envelope.Documents?.FirstOrDefault()
?? throw new NotFoundException($"Document could not be located within the specified envelope. Request details:\n" +
request.ToJson(Format.Json.ForDiagnostics));
if (doc.ByteData is null)
throw new InvalidOperationException($"Document byte data is missing, indicating a potential data integrity issue. Request details:\n" +
request.ToJson(Format.Json.ForDiagnostics));
return doc.Elements?.SelectMany(e => e.Annotations ?? Enumerable.Empty<ElementAnnotation>()).Where(annot => annot is not null).Any() ?? false
? BurnElementAnnotsToPDF(doc.ByteData, doc.Elements)
: BurnInstantJSONAnnotsToPDF(doc.ByteData, await _docStatusRepo
.Where(status => status.EnvelopeId == envelope.Id)
.Select(status => status.Value)
.ToListAsync(cancel));
}
private byte[] BurnElementAnnotsToPDF(byte[] pSourceBuffer, List<Signature> elements)

View File

@ -70,10 +70,10 @@ public static class DependencyInjection
return this;
}
public EGConfiguration AddServices(IConfiguration config)
public EGConfiguration AddServices(IConfiguration config, bool usePdfBurner = false)
{
#pragma warning disable CS0618
_serviceRegs.Enqueue(s => s.AddEnvelopeGeneratorServices(config));
_serviceRegs.Enqueue(s => s.AddEnvelopeGeneratorServices(config, usePdfBurner));
#pragma warning restore CS0618
_addingStatus[nameof(AddServices)] = true;
return this;

View File

@ -1,6 +1,7 @@
using EnvelopeGenerator.Application.Common.Configurations;
using EnvelopeGenerator.Application.Envelopes.Queries;
using EnvelopeGenerator.Application.Pdf;
using EnvelopeGenerator.Domain.Constants;
using EnvelopeGenerator.Finalizer.Models;
using MediatR;
using Microsoft.Extensions.Options;
using Quartz;
@ -11,15 +12,15 @@ namespace EnvelopeGenerator.Finalizer.Job
{
private readonly ILogger<FinishEnvelopeJob> _logger;
private readonly GdPictureOptions _gdPictureOptions;
private readonly IMediator _mediator;
public FinishEnvelopeJob(ILogger<FinishEnvelopeJob> logger, IOptions<GdPictureOptions> gdPictureOptions, IMediator mediator)
private readonly PDFBurnerParams _options;
public FinishEnvelopeJob(ILogger<FinishEnvelopeJob> logger, IMediator mediator, IOptions<PDFBurnerParams> options)
{
_logger = logger;
_gdPictureOptions = gdPictureOptions.Value;
_mediator = mediator;
_options = options.Value;
}
public async Task Execute(IJobExecutionContext context)
@ -28,27 +29,43 @@ namespace EnvelopeGenerator.Finalizer.Job
var envelopes = await _mediator.Send(new ReadEnvelopeQuery()
{
Status = new() { Include = [EnvelopeStatus.EnvelopeCompletelySigned] },
Status = new() { Include = [ EnvelopeStatus.EnvelopeCompletelySigned ] },
HasDocResult = false
}, cancel);
foreach (var envelope in envelopes)
using var semaphore = new SemaphoreSlim(_options.ConcurrencyLimit);
await Task.WhenAll(envelopes.Select(async envelope =>
{
// add sub-steps
await semaphore.WaitAsync(cancel);
try
{
await _mediator.BurnPdf(envelope.Id, cancel);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error burning envelope {EnvelopeId}", envelope.Id);
}
finally
{
semaphore.Release();
}
}));
if (envelopes.Any())
var envelopeCount = envelopes.Count();
if (envelopeCount > 0)
{
_logger.LogInformation(
"Job '{JobName}' executed at {Timestamp}. {EnvelopeCount} envelope(s) successfully finalized. UUID(s): {EnvelopeUuids}",
context.JobDetail.Key.Name,
DateTimeOffset.Now,
envelopes.Count(),
context.FireTimeUtc.ToLocalTime(),
envelopeCount,
string.Join(", ", envelopes.Select(e => e.Uuid))
);
}
else
_logger.LogInformation("Job '{JobName}' executed successfully at {Timestamp}. No envelopes were finalized.",
context.JobDetail.Key.Name,
DateTimeOffset.Now
context.FireTimeUtc.ToLocalTime()
);
}
}

View File

@ -1,15 +1,10 @@
using CommandDotNet.Execution;
using EnvelopeGenerator.Application.ThirdPartyModules.Queries;
using EnvelopeGenerator.DependencyInjection;
using EnvelopeGenerator.Finalizer;
using EnvelopeGenerator.Finalizer.Job;
using EnvelopeGenerator.Finalizer.Models;
using EnvelopeGenerator.Infrastructure;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Quartz;
using Quartz.AspNetCore;
using Quartz.Impl;
using Quartzmon;
using Serilog;
@ -92,7 +87,7 @@ try
.EnableDetailedErrors();
});
})
.AddServices(config)
.AddServices(config, true)
);
#endregion Add DB Context, EG Inf. and Services