using System.Reflection; using DBConnection.ModelBuilders; using DBConnection.Seeders; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Treestar.Shared.Models.DBDomain; namespace DBConnection.Contexts; public abstract class AppDbContext : DbContext { public DbSet Novels { get; set; } public DbSet Chapters { get; set; } public DbSet Authors { get; set; } public DbSet Users { get; set; } public DbSet Tags { get; set; } public DbSet UserNovels { get; set; } protected IConfiguration Configuration { get; set; } protected abstract string ConnectionStringName { get; } private readonly IEnumerable _seeders = from t in Assembly.GetExecutingAssembly().GetTypes() where t.IsClass && (t.Namespace?.Contains(nameof(DBConnection.Seeders)) ?? false) && typeof(ISeeder).IsAssignableFrom(t) select (ISeeder) Activator.CreateInstance(t); private static readonly IEnumerable ModelBuilders = from t in Assembly.GetExecutingAssembly().GetTypes() where t.IsClass && (t.Namespace?.Contains(nameof(DBConnection.ModelBuilders)) ?? false) && typeof(IModelBuilder).IsAssignableFrom(t) select (IModelBuilder) Activator.CreateInstance(t); protected AppDbContext(DbContextOptions options, IConfiguration configuration) : base(options) { Configuration = configuration; } public override Task SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken()) { UpdateAuditInfo(); return base.SaveChangesAsync(cancellationToken); } private void UpdateAuditInfo() { var entries = ChangeTracker.Entries().Where(x => x.Entity is BaseEntity && (x.State == EntityState.Added || x.State == EntityState.Modified)); foreach(var entry in entries) { if (entry.State == EntityState.Added) { ((BaseEntity)entry.Entity).DateCreated = DateTime.Now; } ((BaseEntity)entry.Entity).DateModified = DateTime.Now; } } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); foreach (var builder in ModelBuilders) { builder.BuildModel(modelBuilder); } foreach (var seeder in _seeders) { seeder.SeedData(modelBuilder); } } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { base.OnConfiguring(optionsBuilder); UseSqlConnection(optionsBuilder, Configuration.GetConnectionString(ConnectionStringName)); } protected abstract void UseSqlConnection(DbContextOptionsBuilder builder, string connectionString); }