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:

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:

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

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:
