Search code examples
c#reflectionentity-framework-4

Reflection to build list of EntityTypeConfiguration for Entity Framework CPT5


I don't want to have to add each mapping class manually to the ModelBuilder() so was trying to use my limited knowledge of reflection to register them. This is what I have, and this is the error I am getting:

CODE:

private static ModelBuilder CreateBuilder() {
            var contextBuilder = new ModelBuilder();
            IEnumerable<Type> configurationTypes = typeof(DatabaseFactory)
                .Assembly
                .GetTypes()
                .Where(type => type.IsPublic && type.IsClass && !type.IsAbstract && !type.IsGenericType && typeof(EntityTypeConfiguration).IsAssignableFrom(type) && (type.GetConstructor(Type.EmptyTypes) != null));

            foreach (var configuration in configurationTypes.Select(type => (EntityTypeConfiguration)Activator.CreateInstance(type)))
            {
                contextBuilder.Configurations.Add(configuration);
            }

            return contextBuilder;
        }

ERROR: Error 2 The type arguments for method 'System.Data.Entity.ModelConfiguration.Configuration.ConfigurationRegistrar.Add(System.Data.Entity.ModelConfiguration.EntityTypeConfiguration)' cannot be inferred from the usage. Try specifying the type arguments explicitly. C:\root\development\playground\PostHopeProject\PostHope.Infrastructure.DataAccess\DatabaseFactory.cs 67 17 PostHope.Infrastructure.DataAccess


Solution

  • Original answer:

    http://areaofinterest.wordpress.com/2010/12/08/dynamically-load-entity-configurations-in-ef-codefirst-ctp5/

    The details of the implied solution:

    The above referenced article shows that you can use the dynamic keyword to bypass compile time type checking and thus get around the restriction of attempting to add the configuration to the generic Add() method of the DbModelBuilder. Here's a quick sample:

    // Load all EntityTypeConfiguration<T> from current assembly and add to configurations
    var mapTypes = from t in typeof(LngDbContext).Assembly.GetTypes()
                   where t.BaseType != null && t.BaseType.IsGenericType && t.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>)
                   select t;
    
    foreach (var mapType in mapTypes)
    {
        // note: "dynamic" is a nifty piece of work which bypasses compile time type checking... (urgh??)
        //       Check out: http://msdn.microsoft.com/en-us/library/vstudio/dd264741%28v=vs.100%29.aspx
        dynamic mapInstance = Activator.CreateInstance(mapType);
        modelBuilder.Configurations.Add(mapInstance);
    }
    

    You can read more on using this keyword on MSDN