How do you register DapperExtension ClassMapper subclasses so they are used?

c# dapper dapper-extensions

Question

I've just started playing with DapperExtensions and it looks very promising. However, I'm confused on how to handle registering the ClassMapper subclasses.

I have both a custom PluralizedAutoClassMapper and a regular ClassMapper and I'm trying to use both.

Here's my pluralized mapper...

public class CustomPluralizedMapper<T> : PluralizedAutoClassMapper<T>
where T : class 
{
    private readonly Type[] SinglularTablePocoTypes = new []{
        typeof(LibraryInfo)
    };

    public override void Table(string tableName)
    {
        base.Table(tableName);

        if(SinglularTablePocoTypes.Any(type => string.Equals(type.Name, tableName, StringComparison.CurrentCultureIgnoreCase)))
            TableName = tableName;
    }
}

...and here's the mapper specifically for the LibraryInfo class

public class LibraryInfoMapper : ClassMapper<LibraryInfo>
{
    public LibraryInfoMapper()
    {
        Map(libraryInfo => libraryInfo.Name).Column("LibraryName");
        Map(libraryInfo => libraryInfo.Description).Column("LibraryDescription");
        AutoMap();
    }
}

The PluralizedAutoClassMapper I get to work by calling the following...

DapperExtensions.DapperExtensions.DefaultMapper = typeof(CustomPluralizedMapper<>);

But I'm not sure how to use the other one at the same time. What am I missing?

Accepted Answer

Ok, I figured it out. The issue was because I'm using IoC and my POCOs are in a different assembly from the mappings.

In short, my model has no idea, nor cares about where or how it's being stored. It only defines an interface describing how it needs to interact with that storage. My DAL defines a class which implements that interface and uses SQLite as it's backing storage. Since the mappings only make sense in regards to SQLite, that's where I defined the mappings.

The problem is DapperExtensions reflects into the assembly that defines the POCOs looking for their ClassMappers, but since mine were in a different assembly, they weren't being found.

However, you can tell DapperExtensions to search external assemblies via the following line of code...

DapperExtensions.DapperExtensions.SetMappingAssemblies(new[]{
    assemblyA, assemblyB, ...assemblyN
});

So since my mappings are defined in the same place as my static Mapper class (which has the static 'Initialize' call) all I now have to do is tell DapperExtensions to search there like so...

public static class Mappings
{
    public static void Initialize()
    {
        DapperExtensions.DapperExtensions.DefaultMapper = typeof(CustomPluralizedMapper<>);

        DapperExtensions.DapperExtensions.SetMappingAssemblies(new[]
        {
            typeof(Mappings).Assembly
        });
    }

    public class CustomPluralizedMapper<T> : PluralizedAutoClassMapper<T>
    where T : class 
    {
        ...
    }

    public class LibraryInfoMapper : ClassMapper<LibraryInfo>
    {
        ...
    }
}

And now everything works!

Better yet, since I can specify the table name in the LibraryInfoMapper, there's actually no need for my CustomPluralizedMapper and therefore I can just use the standard PluralizedAutoClassMapper like so...

public static class Mappings
{
    public static void Initialize()
    {
        DapperExtensions.DapperExtensions.DefaultMapper = typeof(PluralizedAutoClassMapper<>);

        DapperExtensions.DapperExtensions.SetMappingAssemblies(new[]
        {
            typeof(Mappings).Assembly
        });
    }

    public class LibraryInfoMapper : ClassMapper<LibraryInfo>
    {
        public LibraryInfoMapper()
        {
            Table("LibraryInfo");
            AutoMap();
        }
    }
}

Done and done! There was ZERO documentation on finding this out so I hope this helps others!



Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why