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