Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass a System.Type into a generic method using reflection [duplicate]

Possible Duplicate:
How to use reflection to call generic Method?

I'm trying to simplify some EF Code First configuration.

Instead of writing code like this:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Asset>().ToTable("Assets");
    modelBuilder.Entity<VideoAsset>().ToTable("VideoAssets");
    modelBuilder.Entity<ImageAsset>().ToTable("ImageAssets");
    ...
}

I'm wrapping the table per type declaration into a class and using reflection to call the modelBuilder

public class TablePerTypeBuilder<TBase> where TBase : class
{
    public void Build(DbModelBuilder modelBuilder)
    {
        //modelBuilder.Entity<Asset>().ToTable("Assets");
        modelBuilder.Entity<TBase>().ToTable(typeof(TBase).Name);

        //modelBuilder.Entity<VideoAsset>().ToTable("VideoAssets");
        //modelBuilder.Entity<ImageAsset>().ToTable("ImageAssets");
        var types = from a in AppDomain.CurrentDomain.GetAssemblies()
                    from t in a.GetTypes()
                    where typeof(TBase).IsAssignableFrom(t)
                    select t;

        foreach (Type type in types)
        {           
            modelBuilder.Entity<type>().ToTable(type.Name); 
            //Error - The type or namespace name 'type' could not be found (are you missing a using directive or an assembly reference?)
        }
    }
}

It's not possible to add a Type as a generic parameter due to compile time safety. So is it possible to make same call using refection?

The aim is to call the builder like

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    TablePerTypeBuilder<Asset> builder = new TablePerTypeBuilder<Asset>();
    builder.Build(modelBuilder);
}
like image 599
Fixer Avatar asked Jun 12 '26 15:06

Fixer


1 Answers

As suggested, you can use MakeGenericMethod(). But its a lot of ugly typing like that:

var method = modelBuilder.GetType().GetMethod("Entity");
var genericMethod = method.MakeGenericMethod(type);
var entTypConfig = genericMethod.Invoke(modelBuilder, null);
entTypConfig.GetType()
    .InvokeMember("ToTable", BindingFlags.InvokeMethod, null, entTypConfig, 
                  new object[] {type.Name});
like image 92
Jan Avatar answered Jun 14 '26 04:06

Jan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!