Stephen York
Stephen York

Reputation: 1429

Generic casting confusion

I'm a little lost on casting generic types and wondering if anyone could please point out what I'm missing.

I have this abstract class definition:

public abstract class BaseEntityTypeConfiguration<TEntity> : IEntityTypeConfiguration<TEntity>
    where TEntity : class
{
    public void Configure(EntityTypeBuilder<TEntity> builder)
    {
        ConfigureEntity(builder);

        var audited = builder as EntityTypeBuilder<IAuditedEntity>;
        audited?.ConfigureAudited();
        
        var timestamped = builder as EntityTypeBuilder<ITimestampEnabled>;
        timestamped?.ConfigureTimestamp();

        var softDelete = builder as EntityTypeBuilder<ISoftDelete>;
        softDelete?.ConfigureSoftDelete();

    }

    public abstract void ConfigureEntity(EntityTypeBuilder<TEntity> builder);

}

In my project this is invoked where TEntity is a Customer class which Implements IAuditedEntity and ITimestampEnabled.

How do I cast the EntityTypeBuilder<TEntity> builder parameter to EntityTypeBuilder<IAuditedEntity>, etc?

Upvotes: 2

Views: 294

Answers (1)

Guru Stron
Guru Stron

Reputation: 141825

One of the options I see is just make ConfigureAudited accept EntityTypeBuilder and not EntityTypeBuilder<TEntity>. But this will complicate the entity setup and possibly make your code not type safe (though maybe it can be worked around using EntityTypeBuilder.Metadata property).

Another option is reflection. You can move your configure methods to static classes (for convenience) and use them something like this:

public static class AuditedEntityExt
{
    public static void ConfigureAudited<T>(EntityTypeBuilder<T> tb) where T : class, IAuditedEntity
    {
        // entity setup
    }
}

public void Configure<T>(EntityTypeBuilder<T> tb) where T: class
{    
    if(typeof(IAuditedEntity).IsAssignableFrom(typeof(T)))
    {
        typeof(AuditedEntityExt).GetMethod(nameof(AuditedEntityExt.ConfigureAudited))
            .MakeGenericMethod(typeof(T))
            .Invoke(null, new[] { tb });
    }
}

Upvotes: 3

Related Questions