ProfK
ProfK

Reputation: 51084

How could I invoke a generic method with dynamically determined type parameters?

I have an IndexModel base class I use for nearly all view models that build an index table of entities:

public class IndexModel<TIndexItem, TEntity> : ViewModel
        where TIndexItem : MappedViewModel<TEntity>, new()
        where TEntity : new()
    {
        public IndexModel()
        {
            Items = new List<TIndexItem>();
        }

        public TIndexItem TemplateItem { get; set; }
        public List<TIndexItem> Items { get; set; }

        public virtual void MapFromEntityList(IEnumerable<TEntity> entityList)
        {
            Items = Mapper.Map<IEnumerable<TEntity>, List<TIndexItem>>(entityList);
        }
    }

I feel the TEntity parameter is unnecessary, as TIndexItem is of type MappedViewModel<TEntity>. My problems are then twofold:

  1. I would need to dynamically invoke MapFromEntityList, using reflection to determine what TEntity is. Constructing the IEnumerable<TEntity> parameter is fairly trivial, but the Mapper.Map<IEnumerable<TEntity>, List<TIndexItem>>(entityList) invocation is a challenge. How can I invoke map with dynamically built type parameters?

  2. My class has the constraint where : MappedViewModel<TEntity>, new(). This is not too big a problem, as I can make this less specific, e.g. where TIndexItem : ViewModel, new(), where ViewModel is an 'untyped' base class for all my view models. Then I can only do the TEntity specific stuff like the mapping call if TIndexItem is a MappedViewModel<TEntity>.

Upvotes: 0

Views: 237

Answers (1)

user1416420
user1416420

Reputation: 498

I think this is what you're after:

public class IndexModel<TEntity> : ViewModel
    where TEntity : new()
{
    public IndexModel()
    {
        Items = new List<MappedViewModel<TEntity>>();
    }

    public MappedViewModel<TEntity>TemplateItem { get; set; }
    public List<MappedViewModel<TEntity>> Items { get; set; }

    public virtual void MapFromEntityList(IEnumerable<TEntity> entityList)
    {
        Items = Mapper.Map<IEnumerable<TEntity>, List<MappedViewModel<TEntity>>>(entityList);
    }

}

Upvotes: 1

Related Questions