TekH 33f7ced3b2 refactor(dependency-injection): replace generic AddDbRepository with configurable registration
- Replaced `AddDbRepository<TDbContext, TEntity>` with `AddDbRepository(Action<RepositoryConfiguration>)` 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.
2025-09-11 13:07:45 +02:00

74 lines
2.6 KiB
C#

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 IServiceCollection AddDbRepository(this IServiceCollection services, Action<RepositoryConfiguration> options)
{
var cfg = new RepositoryConfiguration();
options.Invoke(cfg);
// 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<Action<IServiceCollection>> RegsFromAssembly = new();
// 2. register entities (can overwrite)
internal Queue<Action<IServiceCollection>> RegsEntity = new();
internal RepositoryConfiguration() { }
public RepositoryConfiguration RegisterFromAssembly<TDbContext>(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<TableAttribute>() != null);
foreach (var entityType in entityTypes)
{
// create generic DbRepository<DbContext, TEntity> 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<TDbContext, TEntity>() where TDbContext : DbContext
where TEntity : class
{
static void reg(IServiceCollection services)
=> services.AddScoped<IRepository<TEntity>, DbRepository<TDbContext, TEntity>>();
RegsEntity.Enqueue(reg);
return this;
}
}
private static void InvokeAll<T>(this Queue<Action<T>> queue, T services)
{
while (queue.Count > 0)
queue.Dequeue().Invoke(services);
}
}