Automatic Mapper Generation

For objects that have a lot of public fields and properties, creating mappers can be a tedious exercise even with an intuitive configuration console. If you have 50 classes in your domain object library with an average of 10 properties each then you will have to configure 50 Mappers and 500 Maps!

To make this chore easier the Configuration Console has been turned into an Object Relational Mapping (ORM) tool. If you create your domain objects before you configure their mappers then you can make use of three Attributes supplied by the MAB to decorate your classes, public fields and public properties and then use the Configuration Console to automatically generate your mappers for you.

MapperAttribute

This attribute is used to decorate your basic domain object classes to specify which classes in your library are domain object classes. This implies that domain object classes can be stored in a library mixed in with any other sorts of classes. The MapperAttribute can take an optional mapper name and table name. If these are left blank then the name of the class is taken for the mapper name and the table name is left blank. This attribute will result in a Basic Mapper generated in the MAB configuration. In the following example we show the two optional named parameters to decorate an Animal class and give it a mapper name of Animal Mapper and link to a table called Animals:

[C#]
[Mapper(Name="Animal Mapper", TableName="Animals")]
public class Animal
{
...
}

SuperMapperAttribute

This attribute is used to decorate your domain object super type classes and should be used to decorate the final concrete derived classes. The SuperMapperAttribute can take an optional mapper name, an optional table name, an optional type column name and an optional type column value. If these are all left blank then the name of the base class is taken for the mapper name (please note: this is the class at the top of the inheritance chain that is ultimately derived from System.Object which is quite often further than you want to go), the table name is left blank, the type column name is assumed to be Type and no value is set for the type column value implying that the type column contains the actual super type name rather than a code. This attribute will result in a Super Mapper generated in the MAB configuration. In the following example we convert our Animal class to an abstract base class and add our three super types Cat, Dog and Horse that all use a single character code held in a column called TypeCode:

[C#]
public abstract class Animal
{
...
}

[Mapper(Name="Animal Mapper", TableName="Animals", TypeColumnName="TypeCode", TypeColumnValue="C")]
public class Cat : Animal
{
...
}

[Mapper(Name="Animal Mapper", TableName="Animals", TypeColumnName="TypeCode", TypeColumnValue="D")]
public class Dog : Animal
{
...
}

[Mapper(Name="Animal Mapper", TableName="Animals", TypeColumnName="TypeCode", TypeColumnValue="H")]
public class Horse : Animal
{
...
}

MapAttribute

This attribute is used to decorate your domain object public fields and properties to specify which properties to include in the mappings. This implies that domain object classes can have public properties that are not mapped to data storage. The MapAttribute can take an optional column name. If the column name is not included then the column name is simply left blank. In the following example we expand on our previous code segment to show the class properties decorated with the MapAttribute showing one property where its name does not match with its column counterpart:

[C#]
[Mapper(Name="Animal Mapper", TableName="Animals")]
public class Animal
{
   [Map]
   public Guid Id
   {
   ...
   }

   [Map]
   public string Name
   {
   ...
   }

   [Map(ColumnName="Comments")]
   public string Description
   {
   ...
   }
}

Note that if the class is not decorated with the MapperAttribute or SuperMapperAttribute then any MapAttributes will be ignored. Also the MapAttribute can only be used to decorate public fields or properties. If it is used for any other member type then a compilation error will result and if used to decorate a private field or property then it wll be ignored.

Inherited and Derived Classes

The MAB attributes are inherited so can be used anywhere in the inheritance chain. If you are setting up the mappings for a Super Mapper, for example, then you will need to decorate public fields and properties in the base classes as well as the super type classes. Once again we extend our super mapper example to show the public properties in both the base class and the super type classes:

[C#]
public abstract class Animal
{
   [Map(ColumnName="Identifier")]
   public Guid Id;

   [Map]
   public string Name
   {
   ...
   }
}

[Mapper(Name="Animal Mapper", TableName="Animals", TypeColumnName="TypeCode", TypeColumnValue="C")]
public class Cat : Animal
{
   [Map]
   public int PurrCount
   {
   ...
   }
}

[Mapper(Name="Animal Mapper", TableName="Animals", TypeColumnName="TypeCode", TypeColumnValue="D")]
public class Dog : Animal
{
   [Map]
   public decimal BarkVolume
   {
   ...
   }
}

[Mapper(Name="Animal Mapper", TableName="Animals", TypeColumnName="TypeCode", TypeColumnValue="H")]
public class Horse : Animal
{
   [Map]
   public short SpanSize
   {
   ...
   }
}

Generating the Mappers

Having decorated our domain object classes and compiled them into an assembly or assemblies, the next stage is to turn to the Configuration Console to generate the mappers. First load your config file into the console and then right click on the Mapping Application Block node to reveal the context menu:

Generate Mappers

When you click on the Generate Mappers option it will first ask you to save your config file if you have not already done so:

Save the Configuration before Generating Mappers

Then you will be presented with the standard open file dialog filtered for assembly files only

Open an Assembly

Having selected your assembly it will be searched for decorated domain object classes and mappers generated and displayed on the Configuration Console with a little message to indicate how many domain objects were found:

Generate Mappers Complete

Last edited Jun 16, 2010 at 10:37 AM by ewdev, version 13

Comments

No comments yet.