4

I am working with Dapper and I want to iterate through my model classes and set type mapping for any class having a field decorated with a ColumnAttribute.

public class ColumnAttributeTypeMapper<T> : FallbackTypeMapper
{
    public static readonly string ColumnAttributeName = "ColumnAttribute";

    public ColumnAttributeTypeMapper()
        : base(new SqlMapper.ITypeMap[]
        {
            new CustomPropertyTypeMap(typeof (T), SelectProperty),
            new DefaultTypeMap(typeof (T))
        })
    {
    }
    // implementation of SelectProperty and so on...
    // If required, full implementation is on https://gist.github.com/senjacob/8539127
}

In my model class library, I'm iterating through all possible types; now I need to call the generic ColumnAttributeTypeMapper<T> constructor with the class of the type.

using System.Web;
using Dapper;

[assembly : PreApplicationStartMethod(typeof(Model.Initiator), "RegisterTypeMaps")]

namespace Model
{
    class Initiator
    {
        public static void RegisterTypeMaps()
        {
            var mappedTypes = Assembly.GetAssembly(typeof (Initiator)).GetTypes().Where(
                f =>
                f.GetProperties().Any(
                    p =>
                    p.GetCustomAttributes(false).Any(
                        a => a.GetType().Name == ColumnAttributeTypeMapper<dynamic>.ColumnAttributeName)));

            // I want to skip registering each class manually :P
            // SqlMapper.SetTypeMap(typeof(Model1), new ColumnAttributeTypeMapper<Model1>());
            // SqlMapper.SetTypeMap(typeof(Model2), new ColumnAttributeTypeMapper<Model2>());

            foreach (var mappedType in mappedTypes)
            {
                SqlMapper.SetTypeMap(mappedType, new ColumnAttributeTypeMapper<mappedType>());
            }
        }
    }
}

How can I pass the class from type instead of type 'mappedType' to new ColumnAttributeTypeMapper<classof(mappedType)?>()

I found this as a similar question, but I need to call the generic constructor instead of a generic method with the Type.

If it can not be done, could you please explain the reason?

Answer

This is how the mapping worked as suggested by Tom.

var mapper = typeof(ColumnAttributeTypeMapper<>);
foreach (var mappedType in mappedTypes)
{
    var genericType = mapper.MakeGenericType(new[] { mappedType });
    SqlMapper.SetTypeMap(mappedType, Activator.CreateInstance(genericType) as SqlMapper.ITypeMap);
}
Community
  • 1
  • 1
Sen Jacob
  • 3,384
  • 3
  • 35
  • 61
  • [C sharp dynamic generic type](http://stackoverflow.com/questions/2078914/c-sharp-dynamic-generic-type) | [Dynamically create a generic type in C#](http://stackoverflow.com/questions/67370/dynamically-create-a-generic-type-for-template) – Sen Jacob Jan 21 '14 at 18:41

1 Answers1

3

You will need the method Type.MakeGenericType; usage is as follows:

var columnType = typeof(ColumnAttributeTypeMapper<>);
var genericColumn = columnType.MakeGenericType(new[] {typeof(mappedType)});
var instance = Activator.CreateInstance(genericColumn);

I'm writing this without intellisense and only having skimmed your code, so please let me know whether I've made any mistakes and I'll correct them.

Tom W
  • 5,108
  • 4
  • 30
  • 52