Bulk register IEntityTypeConfiguration<> entity framework core

c# entity-framework-core

Question

Ok, so i am using entity framework with dot net core and code first migrations. This isn't a problem as such, i just wondered if anyone had come across a better way of doing this.

Currently i have many entity type configurations like so

public class ExampleEntityConfiguration : IEntityTypeConfiguration<ExampleEntity>
{
   public void Configure(EntityTypeBuilder<ExampleEntity> builder)
   {
      builder.Property(p => p.Id).ValueGeneratedNever();

      // more options here
   }
}

and i register them in my dbcontext like so

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
  base.OnModelCreating(modelBuilder);

  modelBuilder.ApplyConfiguration(new ExampleEntityConfiguration());

  // lot's more configurations here
}

has anyone come across or know of a way to register all the IEntityTypeConfiguration interfaces?

It just seems like a lot of repetitive code that could be solved by getting a list of the configurations, looping over them and applying in the context. I just don't know where to start with getting a list of IEntityTypeConfiguration classes that exist in a particular namespace.

Any help/suggestions would be great.

1
19
10/30/2017 11:18:46 AM

Accepted Answer

It can be done with reflection like this:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);    
    // get ApplyConfiguration method with reflection
    var applyGenericMethod = typeof(ModelBuilder).GetMethod("ApplyConfiguration", BindingFlags.Instance | BindingFlags.Public);            
    // replace GetExecutingAssembly with assembly where your configurations are if necessary
    foreach (var type in Assembly.GetExecutingAssembly().GetTypes()
        .Where(c => c.IsClass && !c.IsAbstract && !c.ContainsGenericParameters)) 
    {
        // use type.Namespace to filter by namespace if necessary
        foreach (var iface in type.GetInterfaces()) {
            // if type implements interface IEntityTypeConfiguration<SomeEntity>
            if (iface.IsConstructedGenericType && iface.GetGenericTypeDefinition() == typeof(IEntityTypeConfiguration<>)) {
                // make concrete ApplyConfiguration<SomeEntity> method
                var applyConcreteMethod = applyGenericMethod.MakeGenericMethod(iface.GenericTypeArguments[0]);
                // and invoke that with fresh instance of your configuration type
                applyConcreteMethod.Invoke(modelBuilder, new object[] {Activator.CreateInstance(type)});
                break;
            }
        }
    }
}
20
10/30/2017 11:37:13 AM

Popular Answer

Using EF Core 2.2+, it got much simpler:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
   Assembly assemblyWithConfigurations = GetType().Assembly; //get whatever assembly you want
   modelBuilder.ApplyConfigurationsFromAssembly(assemblyWithConfigurations);
}


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow