Mapping Application Block 4.1
The Mapping Application Block completes the Object Relational Mapping (ORM)
tool started with the Query Application Block (QAB) by taking the Data Transfer Object (DTO) produced from the QAB and mapping it to a configured domain object or
taking a domain object and producing a DTO to pass to the QAB. All configuration of such mappings naturally uses the Enterprise Library Configuration Console.
In essence the MAB, combined with the QAB, gives the same functionality as the Entity Framework
, bringing an ORM
tool to the Enterprise Library. The Configuration Console plays its part too as the user interface to the ORM tool. All queries to data sources and object mappings are configured using the console and mappings can even be autogenerated by reading from a domain object assembly.
So, if you have built the MAB to work with the QAB then why two blocks? The clue to the main answer is in the name of the object passed between the two blocks called a "Data Transfer Object (DTO)"
. This implies that data is being transferred from one place to another. Just suppose that one place is a continent away from the other? Then we are probably going to need some form of messaging system in between. Not only that but in Enterprise development the QAB sits firmly in the Data tier
whilst the MAB is all about the domain which sits firmly in the Business tier
(sometimes also known as the Application tier
or even Domain tier
). The split is, thus, deliberate to separate "data concerns" from "business concerns" and allow for a logical and even physical separation of the two. In a "cloud"
scenario it would be possible to publish data to the "cloud" in a consistent DTO format for clients using MAB to consume and convert to an application specific domain. In a sense it is nothing much short of serialising and deserialising from a data store using permanent storage media to a domain object in memory and back again, but done in such a way that the business layer does not need to know about the data store and the data layer does not need to know about the domain objects and scalable from all this happening on a single machine between its hard disk and RAM to several machines spread across continents where the RAM memory object that gets consumed could be on a machine in a different country to the machine that hosts the hard disk that stores the object permanently.
The other reason is that whilst the MAB is dependent on the DataSet
type as its DTO, that does not
mean it is dependent on the QAB. If you have other processes for producing DataSets then the MAB can be used with those processes to convert to and from strongly typed domain objects without the need for the QAB. Similarly, if you are not interested in building a library of strongly typed domain objects and simply want to display raw data on a screen or web page then you can use the QAB without the need for the MAB making use of the ability to bind DataSets to various visual controls and the features of a DataSet to allow for and keep track of data changes etc.
The developer is not limited to the providers out-of-the-box but can extend the block by adding providers of their own in the normal Enterprise Library extensible fashion.
The following are the main features associated with the Mapping Application Block:
- Any domain object can be serialised to a DataSet for interfacing to the QAB or any other process that consumes DataSets.
- Any domain object can be deserialised from a DataSet supplied by the QAB, or any other process that supplies DataSets.
- The MAB can support a standard single mapping between a data store, such as a table, and a domain object using a Basic Mapper. The MAB, however, can also support multiple super types stored in a single data store location. For example, say you had several domain object animal super types such as Cat, Dog and Horse all inheriting from an Animal abstract class, then these might be stored in a single data storage table called Animal with one column dedicated to defining the super type e.g. a char(1) column, containing the values "C", "D" or "H". This scenario can be configured within the MAB using a Super Mapper.
- Configuration facility for Mappers and Maps where a mapper is a provider that converts between domain objects and DataSets and a map defines the relationship between a column of a DataSet table and a public property of a domain object.
- You can use either the stand-alone Enterprise Library Configuration Console or the Visual Studio integrated Console to manage all Mapping Application Block settings.
- If you need to manage data from a mapper type or map type not currently supported, then you can extend the application block by creating custom mapper providers and custom map providers
- Attributes are provided to decorate pre-built domain objects so that mapper configuration can be generated automatically through the Configuration Console.
- Management and monitoring features include instrumentation features such as Performance Counters, Windows EventLog logging and WMI events. Windows Active Directory Group Policy features are not included with the MAB as there was no perceived benefit in doing so.
- Dependency Injection support. The Mapping Application Block integrates with Unity v1.2 for the creation of all its objects.
If you need convincing as to why you would use this block, have a look at the following reasons:
- You need an ORM tool to rapidly build a Data Access Layer.
- You need an ORM tool that will split data concerns from domain concerns and scale across a physical service layer.
- You want to be able to map domain objects to various data source types e.g. data tables, XML files or even services.
- You want complete flexibility with the design of your domain objects without any restrictions imposed by your ORM tool (one caveat is that you do need a parameterless constructor).
- You want to use a familiar configuration interface for your mappings that you already use for your globalised resources, data queries, data access, exception handling and logging etc.
A Quick Code Sample
The following code sample shows the basic function of the block; how to create a collection of objects from a data store:
// create a collection of MyObject objects by querying the data store
Collection<MyObject> myObjectCollection = MappingFactory.CreateMapper("MyObject Mapper").ToDomainObjectCollection<MyObject>(QueryFactory.CreateQuery("Read MyObject").ExecuteForRead());
This next code sample shows how create a specific object from a data store:
// create a specific MyObject object by querying the data store with parameters
IDictionary<string, object> parameters = new Dictionary<string, object>();
MyObject myObject = MappingFactory.CreateMapper("MyObject Mapper").ToDomainObject<MyObject>(QueryFactory.CreateQuery("Read MyObject By Id").ExecuteForRead(parameters));
This next code sample shows how to write an object away to a data store using the DataSet parameter syntax of the ExecuteForWrite()
// write an object away to a data store
MyObject myObject = new MyObject();
myObject.Id = Guid.NewGuid();
myObject.Name = "Fred";
myObject.Description = "A good friend";
QueryFactory.CreateQuery("Write MyObject").ExecuteForWrite(MappingFactory.CreateMapper("MyObject Mapper").FromDomainObject(myObject));
Installing the Assemblies
When you build the Mapping Application Block
the assemblies are compiled without a strong name key. If you want to put these assemblies into the GAC then you will need to assign a strong name key to each assembly and recompile (this is not neccessary for any design.dll
assembly). If you use the BuildLibraryAndCopyAssemblies.bat
console script then the assemblies are copied to the EntLibContrib bin
folder. You can reference the assemblies from here for your application however; to use the Configuration console you will need to copy all of the following assemblies to your installation of the Enterprise Library Configuration Console which is usually in C:\Program Files\Microsoft Enterprise Library 4.1 - October 2008\Bin
The Mapping Application Block 4.1 consists of the following assemblies:
- EntLibContrib.Mapping.dll - the main assembly for the block
- EntLibContrib.Mapping.Configuration.Design.dll - the plug-in interface to the Enterprise Library Configuration Console for the Mapping Application Block.
- EntLibContrib.Common.dll - Common Core code shared between all EntLibContrib extensions
- EntLibContrib.Common.Configuration.Design.dll - Common Configuration Console design code, shared between all EntLibContrib extensions
The MAB is inspired by the ideas in Martin Fowler's
book Patterns of Enterprise Application Architecture
. The Mapping Application Block implements the Domain Model, Identity Field, Data Transfer Object, Data Mapper, Inheritance Mapper, Mapper, Metadata Mapping, Plugin, Record Set and Single Table Inheritance patterns. The Mapping Application Block (MAB) complements the Query Application Block (QAB) to complete the implementation of PoEAA by adding configurable Object Relational Mapping to a Domain Model.