From 33f7ced3b2d94cd69835f4dec95f650e7656bb0b Mon Sep 17 00:00:00 2001 From: TekH Date: Thu, 11 Sep 2025 13:07:45 +0200 Subject: [PATCH] refactor(dependency-injection): replace generic AddDbRepository with configurable registration - Replaced `AddDbRepository` with `AddDbRepository(Action)` for more flexible DI registration. - Added `RepositoryConfiguration` class to support: - Registering repositories from an assembly (`RegisterFromAssembly`) - Registering individual entities (`RegisterEntity`) - Queues (`RegsFromAssembly` and `RegsEntity`) are used to defer registration until `InvokeAll` is called. - Allows overriding and scanning multiple entities dynamically instead of static generic method. --- .../DependencyInjection.cs | 69 +++++++++++++++++-- 1 file changed, 62 insertions(+), 7 deletions(-) diff --git a/DigitalData.Core.Infrastructure/DependencyInjection.cs b/DigitalData.Core.Infrastructure/DependencyInjection.cs index 8626da9..a2756b3 100644 --- a/DigitalData.Core.Infrastructure/DependencyInjection.cs +++ b/DigitalData.Core.Infrastructure/DependencyInjection.cs @@ -1,19 +1,74 @@ using DigitalData.Core.Abstraction.Application.Repository; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; +using System.ComponentModel.DataAnnotations.Schema; +using System.Reflection; namespace DigitalData.Core.Infrastructure; public static class DependencyInjection { - public static EntityConfigurationOptions AddDbRepository(this IServiceCollection services, Func> queryFactory) - where TDbContext : DbContext - where TEntity : class + public static IServiceCollection AddDbRepository(this IServiceCollection services, Action options) { - services - .AddScoped, DbRepository>() - .AddSingleton(queryFactory); + var cfg = new RepositoryConfiguration(); + options.Invoke(cfg); - return new EntityConfigurationOptions(services); + // 1. FromAssembly + cfg.RegsFromAssembly.InvokeAll(services); + + // 2. Entities to be able overwrite + cfg.RegsEntity.InvokeAll(services); + + return services; + } + + public class RepositoryConfiguration + { + // 1. register from assembly + internal Queue> RegsFromAssembly = new(); + + // 2. register entities (can overwrite) + internal Queue> RegsEntity = new(); + + internal RepositoryConfiguration() { } + + public RepositoryConfiguration RegisterFromAssembly(Assembly assembly) where TDbContext : DbContext + { + void reg(IServiceCollection services) + { + // scan all types in the Assembly + var entityTypes = assembly.GetTypes() + .Where(t => t.IsClass && !t.IsAbstract && t.GetCustomAttribute() != null); + + foreach (var entityType in entityTypes) + { + // create generic DbRepository type + var repositoryType = typeof(DbRepository<,>).MakeGenericType(typeof(TDbContext), entityType); + var interfaceType = typeof(IRepository<>).MakeGenericType(entityType); + + // add into DI container as Scoped + services.AddScoped(interfaceType, repositoryType); + } + } + + RegsFromAssembly.Enqueue(reg); + return this; + } + + public RepositoryConfiguration RegisterEntity() where TDbContext : DbContext + where TEntity : class + { + static void reg(IServiceCollection services) + => services.AddScoped, DbRepository>(); + + RegsEntity.Enqueue(reg); + return this; + } + } + + private static void InvokeAll(this Queue> queue, T services) + { + while (queue.Count > 0) + queue.Dequeue().Invoke(services); } } \ No newline at end of file