feat(MappingOptions): add to configure UriBuilderOptions factories.

- add WorkFlowServiceOptions for flexible configuration
This commit is contained in:
tekh 2025-08-04 14:01:13 +02:00
parent eafdc17b70
commit 581bd22c24
6 changed files with 113 additions and 20 deletions

View File

@ -47,7 +47,11 @@ try
?? throw new InvalidOperationException(
"The 'MediatRLicense' configuration value is missing or empty." +
"Please ensure it is properly set in the configuration source.");
builder.Services.AddWorkFlowServices(mediatRLicense).AddWorkFlowRepositories();
builder.Services.AddWorkFlowServices(opt =>
{
opt.MediatRLicense = mediatRLicense;
opt.ConfigMapping(config);
}).AddWorkFlowRepositories();
builder.Services.AddUserManager<WFDBContext>();

View File

@ -0,0 +1,17 @@
{
"MappingOptions": {
"TfFileUri": {
"Scheme": "https",
"Host": " dd-gan.digitaldata.works",
"Port": 8443,
"Path": "api/file"
},
"TfFileIconUri": {
"Scheme": "https",
"Host": " dd-gan.digitaldata.works",
"Port": 8443,
"Path": "api/file",
"Query": "icon=true"
}
}
}

View File

@ -1,30 +1,52 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using WorkFlow.Application.Mapping;
namespace WorkFlow.Application;
public static class DependencyInjection
{
public static IServiceCollection AddWorkFlowServices(this IServiceCollection services, string mediatRLicense, Action<WorkFlowServiceOptions>? options = null)
public static IServiceCollection AddWorkFlowServices(this IServiceCollection services, Action<WorkFlowServiceOptions>? options = null)
{
WorkFlowServiceOptions diOptions = new();
options?.Invoke(diOptions);
WorkFlowServiceOptions sOptions = new(services);
options?.Invoke(sOptions);
services.AddAutoMapper(typeof(MappingProfile).Assembly);
services.AddMediatR(cfg =>
{
cfg.RegisterServicesFromAssembly(typeof(DependencyInjection).Assembly);
cfg.LicenseKey = mediatRLicense;
cfg.LicenseKey = sOptions.MediatRLicense;
});
services.AddSingleton(diOptions.UriBuilderFactory());
if(!sOptions.IsMappingConfigured)
services.Configure<MappingOptions>(_ => { });
services.AddTransient<TfFileUriBuilderResolver>();
services.AddTransient<TfFileIconUriBuilderResolver>();
return services;
}
public class WorkFlowServiceOptions
{
public Func<UriBuilder> UriBuilderFactory { get; set; } = () => new UriBuilder();
private readonly IServiceCollection _services;
internal bool IsMappingConfigured { get; private set; } = false;
public WorkFlowServiceOptions(IServiceCollection services) => _services = services;
private void EnsureSingleMappingConfiguration(Action action)
{
if (IsMappingConfigured)
throw new InvalidOperationException("Mapping configuration has already been set.");
action();
IsMappingConfigured = true;
}
public void ConfigMapping(IConfiguration config) => EnsureSingleMappingConfiguration(() => _services.Configure<MappingOptions>(config));
public void ConfigMapping(Action<MappingOptions> options) => EnsureSingleMappingConfiguration(() => _services.Configure(options));
public string? MediatRLicense { get; set; }
}
}

View File

@ -0,0 +1,52 @@
namespace WorkFlow.Application.Mapping;
public class MappingOptions
{
public UriBuilderOptions TfFileUri { get; set; } = new();
public UriBuilderOptions TfFileIconUri { get; set; } = new();
public class UriBuilderOptions
{
public string? Scheme { get; set; }
public string? Host { get; set; }
public int? Port { get; set; }
private string _path = "/";
public string Path
{
get => _path;
set => _path = value.Trim('/');
}
private string _query = string.Empty;
public string Query
{
get => _query;
set => _query = value.TrimStart('?');
}
public UriBuilder ToBuilder
{
get
{
var uriBuilder = new UriBuilder()
{
Scheme = Scheme ?? "http",
Host = Host ?? "localhost",
Path = Path,
Query = Query,
};
if (Port is int port)
uriBuilder.Port = port;
return uriBuilder;
}
}
}
}

View File

@ -1,4 +1,5 @@
using AutoMapper;
using Microsoft.Extensions.Options;
using System.Web;
using WorkFlow.Application.Dto;
using WorkFlow.Domain.Entities;
@ -7,16 +8,14 @@ namespace WorkFlow.Application.Mapping;
public class TfFileIconUriBuilderResolver : IValueResolver<TfFile, TfFileDto, UriBuilder?>
{
private readonly UriBuilder _uriBuilder;
private readonly Func<UriBuilder> _uriBuilderFactory;
public TfFileIconUriBuilderResolver(UriBuilder uriBuilder) => _uriBuilder = uriBuilder;
public TfFileIconUriBuilderResolver(IOptions<MappingOptions> options) => _uriBuilderFactory = () => options.Value.TfFileIconUri.ToBuilder;
public UriBuilder? Resolve(TfFile source, TfFileDto destination, UriBuilder? destMember, ResolutionContext context)
{
var builder = new UriBuilder(_uriBuilder.Uri)
{
Path = HttpUtility.UrlEncode(source.Icon)
};
var builder = _uriBuilderFactory();
builder.Path = HttpUtility.UrlEncode(source.Icon);
return builder;
}
}

View File

@ -1,4 +1,5 @@
using AutoMapper;
using Microsoft.Extensions.Options;
using System.Web;
using WorkFlow.Application.Dto;
using WorkFlow.Domain.Entities;
@ -7,16 +8,14 @@ namespace WorkFlow.Application.Mapping;
public class TfFileUriBuilderResolver : IValueResolver<TfFile, TfFileDto, UriBuilder?>
{
private readonly UriBuilder _uriBuilder;
private readonly Func<UriBuilder> _uriBuilderFactory;
public TfFileUriBuilderResolver(UriBuilder uriBuilder) => _uriBuilder = uriBuilder;
public TfFileUriBuilderResolver(IOptions<MappingOptions> options) => _uriBuilderFactory = () => options.Value.TfFileUri.ToBuilder;
public UriBuilder? Resolve(TfFile source, TfFileDto destination, UriBuilder? destMember, ResolutionContext context)
{
var builder = new UriBuilder(_uriBuilder.Uri)
{
Path = HttpUtility.UrlEncode(source.Path)
};
var builder = _uriBuilderFactory();
builder.Path = HttpUtility.UrlEncode(source.Path);
return builder;
}
}