I have been seeing and using AutoMapper with greater frequency recently. Its premise is simple yet incredibly useful in the grand scheme of things. Automapper provides a very clean and intuitive way to map types. We have all had the tedious task of getting code from the database layer into a service layer, or from Entity Framework to … something else. The code associated with this type of mapping has either been stored in some ill conceived utility class or even worse it sits at the implementation layer before the output code is returned. Either way, mapping code is uninspiring and how we have been doing it has been just wrong. This is how I now solve that problem:
Install AutoMapper from the Package Manager console as follows (it is a single assembly download):
PM> Install-Package AutoMapper
In most of the instances I have been using the static Mapper method, which should only occur once per AppDomain. For an ASP.NET application, for example, that would probably be completed in the Application_OnStart event of the Global.asax.cs file. For the sake of a rudimentary example lets consider the following basics types, one that is returned from a database API (EmployeeDB) and one which would be used to return data frEom a service endpoint (Employee).
public class EmployeeDB { public string FirstName { get; set; } public string LastName { get; set; } public DateTime DOB { get; set; } public string SSN { get; set; } } public class Employee { public string Name { get; set; } public int Age { get; set; } public string SSN { get; set; } }
We need to shoe horn those EmployeeDB fields into our service layer type, and in the following example I show examples of explicit and implicit mapping within the Global.asax:
<%@ Application Language="C#" %> <%@ Import Namespace="WebSite1" %> <%@ Import Namespace="System.Web.Optimization" %> <%@ Import Namespace="System.Web.Routing" %> <%@ Import Namespace="AutoMapper" %> void Application_Start(object sender, EventArgs e) { // Code that runs on application startup BundleConfig.RegisterBundles(BundleTable.Bundles); AuthConfig.RegisterOpenAuth(); RouteConfig.RegisterRoutes(RouteTable.Routes); CreateMapping(); } private void CreateMapping() { //Explicitly maps 'First name' and 'Last name' to 'Name' //Explicitly maps 'Age' from 'Date of birth' //Implicitly matches 'SSN' to 'SSN' no configuration required Mapper.CreateMap() .ForMember(emp => emp.Name, empdb => empdb.MapFrom(n => n.FirstName + " " + n.LastName)) .ForMember(emp => emp.Age, empdb => empdb.MapFrom(n => DateTime.Now.Year - n.DOB.Year)); } Immediately upon start up this web application Mapper knows how I intend to convert EmployeeDB to Employee:
protected void Page_Load(object sender, EventArgs e) { //retrieve from a DB layer EmployeeDB employeedb = new EmployeeDB() { DOB = DateTime.Now.AddYears(-42), FirstName = "Dominic", LastName = "Cobb", SSN = "111-11-1111" }; //employee now has all the converted properties from employee db //ready to be used at service layer var employee = Mapper.Map(employeedb); } Of course you can use this technique in any type of application you like.
Here are a list of some advanced AutoMapping techniques:
- Flattening
- Projection
- Configuration Validation
- Lists and Arrays
- Nested Mappings
- Custom Type Converters
- Custom Value Resolvers
- Null Substitution
- Containers
- Mapping Inheritance
- Queryable Extensions
Happy mapping people!
Comments are closed.