using System; using System.Linq; using Microsoft.EntityFrameworkCore; using xCommons.Extensions; using xDataService.Configuration; using xDataService.Helpers; using xDataService.Providers; namespace xDataService.Db { /// /// Provide an abstraction layout arround DBContext ... /// Only Used on EFCore ... /// public abstract class XDbContext : DbContext { // #region Properties ... private readonly string database; private readonly XDataServiceConfiguration config; private readonly string[] dynamicEntityRegisterarsNames; private readonly XEntityRegisterarHandlerService dynamicEntityHandlers; #endregion // #region Entities ... // // Register Default and Base Entities ... #endregion // #region Constructor ... public XDbContext( string database, DbContextOptions options, XDataServiceConfiguration config, XEntityRegisterarHandlerService dynamicEntityHandlers, string[] dynamicEntityRegisterarsNames = null ) : base(options) { // try { Database.EnsureCreated(); Database.Migrate(); } catch { } // this.config = config; this.database = database; this.dynamicEntityHandlers = dynamicEntityHandlers; this.dynamicEntityRegisterarsNames = dynamicEntityRegisterarsNames; // // Handling DbSets of Dynamic Entities ... if (!dynamicEntityHandlers.IsNull()) { // // Configure XEntityRegisterarHandlerService ... dynamicEntityHandlers.HandleRegisteredEntities(); // // Loop through Entity Types ... foreach (var entityType in dynamicEntityHandlers.GetEntityTypes(dynamicEntityRegisterarsNames)) { // try { // // Use reflection to call Set() var method = typeof(XDbContext) .GetMethod(nameof(XDbContext.Set), Type.EmptyTypes) .MakeGenericMethod(entityType); if (!method.IsNull()) { method.Invoke(this, null); } } catch { } } } } #endregion /// /// Extract Current Database Configuration ... /// /// public XDataBaseConfiguration GetDatabaseConfiguration() { // XDataBaseConfiguration result = config.Databases.FirstOrDefault(db => string .Equals(db.Key, database, StringComparison.InvariantCultureIgnoreCase)).Value; // return result; } // #region Overrides ... // // Prepare Model Configs ... protected override void OnModelCreating(ModelBuilder modelBuilder) { // OnXModelCreating(modelBuilder); // // Automatically apply all IEntityTypeConfiguration in this assembly modelBuilder.ApplyConfigurationsFromAssembly(typeof(XDbContext).Assembly); // // Extract Entity Container Assemblies ... var entityAssemblies = XDataServiceHelper.ExtractEntityAssemblies(); foreach(var assembly in entityAssemblies) { modelBuilder.ApplyConfigurationsFromAssembly(assembly); } // // Check Dynamic Registered Service is Exists or not ... if (!dynamicEntityHandlers.IsNull()) { // // Set Entity of Dynamically Registered Entities ... foreach (var entityType in dynamicEntityHandlers.GetEntityTypes(dynamicEntityRegisterarsNames)) { modelBuilder.Entity(entityType); } // // Configure Entity using Provided Registerar ... dynamicEntityHandlers .HandleApplyRegisteredEntitiesConfigurations(modelBuilder, dynamicEntityRegisterarsNames); } // // Since this class inherit from Identity Db Context, // we have to pass this to Building Identity Models ... base.OnModelCreating(modelBuilder); } // // Prepare Configuring ... protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { // if (config.EnableDetailedErrors) { optionsBuilder.EnableDetailedErrors(); } // if (config.EnableSensitiveDataLogging) { optionsBuilder.EnableSensitiveDataLogging(); } // if (config.EnableTracking) { optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.TrackAll); } else { optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); } // OnXConfiguring(optionsBuilder); // base.OnConfiguring(optionsBuilder); } #endregion // #region Abstracts ... // public abstract void OnXModelCreating(ModelBuilder modelBuilder); // public abstract void OnXConfiguring(DbContextOptionsBuilder optionsBuilder); #endregion // #region Dynamic DbSet(s) ... public override DbSet Set() where TEntity : class { return base.Set(); } #endregion } }