diff --git a/MaddoShared/IImageCreator.cs b/MaddoShared/IImageCreator.cs new file mode 100644 index 0000000..6fd85a5 --- /dev/null +++ b/MaddoShared/IImageCreator.cs @@ -0,0 +1,9 @@ +using System.Drawing; +using System.Threading.Tasks; + +namespace MaddoShared; + +public interface IImageCreator +{ + Task CreateImageAsync(ImageState imgState, Image logo); +} diff --git a/MaddoShared/ImageCreationStuff.cs b/MaddoShared/ImageCreationStuff.cs index 7aef4d4..b688f3a 100644 --- a/MaddoShared/ImageCreationStuff.cs +++ b/MaddoShared/ImageCreationStuff.cs @@ -18,7 +18,7 @@ namespace MaddoShared public class ImageCreationStuff( ILogger logger, PicSettings picSettings, - ImageCreatorSharp imageCreatorService) + IImageCreator imageCreatorService) { public class Options { diff --git a/MaddoShared/ImageCreatorAlternate.cs b/MaddoShared/ImageCreatorAlternate.cs new file mode 100644 index 0000000..2c945e8 --- /dev/null +++ b/MaddoShared/ImageCreatorAlternate.cs @@ -0,0 +1,25 @@ +using System.Drawing; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; + +namespace MaddoShared; + +// Minimal alternate adapter that currently delegates to ImageCreatorSharp. +// Later this can be replaced with a different library implementation. +public class ImageCreatorAlternate : IImageCreator +{ + private readonly ImageCreatorSharp _inner; + private readonly ILogger _logger; + + public ImageCreatorAlternate(ImageCreatorSharp inner, ILogger logger) + { + _inner = inner; + _logger = logger; + } + + public Task CreateImageAsync(ImageState imgState, Image logo) + { + _logger.LogDebug("Using alternate image creator adapter"); + return _inner.CreateImageAsync(imgState, logo); + } +} diff --git a/MaddoShared/ImageCreatorMapper.cs b/MaddoShared/ImageCreatorMapper.cs new file mode 100644 index 0000000..8ee07cf --- /dev/null +++ b/MaddoShared/ImageCreatorMapper.cs @@ -0,0 +1,49 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; + +namespace MaddoShared; + +/// +/// Dynamically resolves the concrete IImageCreator implementation at call time +/// based on current PicSettings.ImageCreatorProvider. +/// +public class ImageCreatorMapper : IImageCreator +{ + private readonly IServiceProvider _sp; + private readonly PicSettings _settings; + private readonly ILogger _logger; + + public ImageCreatorMapper(IServiceProvider sp, PicSettings settings, ILogger logger) + { + _sp = sp ?? throw new ArgumentNullException(nameof(sp)); + _settings = settings ?? throw new ArgumentNullException(nameof(settings)); + _logger = logger; + } + + public Task CreateImageAsync(ImageState imgState, System.Drawing.Image logo) + { + var provider = (_settings.ImageCreatorProvider ?? "Sharp").Trim(); + _logger?.LogDebug("Resolving IImageCreator for provider '{Provider}'", provider); + + return provider.Equals("ALTERNATE", StringComparison.OrdinalIgnoreCase) + ? ResolveAndCall(imgState, logo) + : ResolveAndCall(imgState, logo); + } + + private Task ResolveAndCall(ImageState imgState, System.Drawing.Image logo) where T : IImageCreator + { + // Resolve the concrete implementation and forward the call + var impl = (IImageCreator)_sp.GetService(typeof(T)); + if (impl is null) + { + _logger?.LogWarning("Requested image creator {Type} is not registered. Falling back to ImageCreatorSharp.", typeof(T).Name); + impl = (IImageCreator)_sp.GetService(typeof(ImageCreatorSharp)); + } + + if (impl is null) + throw new InvalidOperationException("No IImageCreator implementation is registered."); + + return impl.CreateImageAsync(imgState, logo); + } +} diff --git a/MaddoShared/ImageCreatorSharp.cs b/MaddoShared/ImageCreatorSharp.cs index 0fdb25e..cfd54e2 100644 --- a/MaddoShared/ImageCreatorSharp.cs +++ b/MaddoShared/ImageCreatorSharp.cs @@ -15,7 +15,7 @@ using SixLabors.ImageSharp.Metadata.Profiles.Exif; namespace MaddoShared; [SuppressMessage("Interoperability", "CA1416:Validate platform compatibility")] -public class ImageCreatorSharp(PicSettings picSettings, ILogger logger) +public class ImageCreatorSharp(PicSettings picSettings, ILogger logger) : IImageCreator { public async Task CreateImageAsync(ImageState imgState, Image logo) { diff --git a/MaddoShared/PicSettings.cs b/MaddoShared/PicSettings.cs index 7472b63..d16cf5f 100644 --- a/MaddoShared/PicSettings.cs +++ b/MaddoShared/PicSettings.cs @@ -66,4 +66,6 @@ public class PicSettings public bool FotoRuotaASinistra { get; set; } = false; public string TempMinText { get; set; } = string.Empty; public bool OverwriteFiles { get; set; } = false; + // Which image creator to use: "Sharp" for current implementation, "Alternate" for alternate library + public string ImageCreatorProvider { get; set; } = "Sharp"; } \ No newline at end of file diff --git a/imagecatalog/Program.cs b/imagecatalog/Program.cs index 451afbd..c14bca6 100644 --- a/imagecatalog/Program.cs +++ b/imagecatalog/Program.cs @@ -103,6 +103,11 @@ static class Program services.AddTransient(); services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + + // Register IImageCreator to be resolved via ImageCreatorMapper which selects concrete implementation at call time + services.AddTransient(sp => sp.GetRequiredService()); // Register a ParametriSetup singleton that persists user preferences in LocalApplicationData var userPrefsPath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),