6 min read

(For more resources related to this topic, see here.)

In this article, we will create a sample project based on a transit system. We will use AutoMapper to help us transform our domain objects to ViewModel objects that we will use in the presentation layer.

Before we begin, we need to explain the business overview of our domain objects used in the transit system. There are four main domain objects that we will work with. TransitStop will be the main entry point to our system; this represents a bus stop in the real world. The TransitStop domain object provides a commuter GeoLocation to give the latitude and longitude of the location, which would allow a commuter to easily locate nearby bus stops in a map if they desire to. A commuter can also use its UniqueNumber to find out when the next bus will be arriving at the bus stop. Each TransitStop has a UniqueNumber identifier so that a commuter can easily locate the stop without a GPS device.

From there, we have the Transit object, which represents the vehicle that will be arriving at the stop. There could be multiples vehicles arriving, and everyone has an arrival time object representing the arrival time of the bus/transit to the stop for the commuter to go from one destination to the other. The following screenshot shows us the overall model:

Step 1 – defining the ViewModel object

Our first view model that we will define and use in our presentation layer will be the BusStopViewModel object, which will be mapped from TransitStop. The following screenshot represents the same:

The preceding screenshot shows the class diagram of our BusStopViewModel and TransitStop domain objects. The code for the same is defined as follows:

public class BusStopViewModel { public string Name { get; set; } public GeoLocationViewModel Location { get; set; } public int TransitStopNumber { get; set; } }

Compare that to our domain object, as in the following code:

public class TransitStop { public string StationName { get; set; } public int UniqueNumber { get; set; } public GeoLocation Location { get; set; } public IEnumerable<Transit> Buses { get; set; } public string GetName() { return string.Format("{0} - {1}", UniqueNumber, StationName); } }

Our ViewModel object will most likely have a different structure than our domain object, since there are properties or data that do not pertain to the presentation layer but are required for our domain object.

Note that the naming convention in BusStopViewModel is mostly identical; in doing so, we will have AutoMapper automatically map the data for us.

Step 2 – creating the mapping

In our mapping code, we will use a repository to get the data. Our repository will be an in-memory data that we generate; however, in real-world situations, one would use a WCF web service, WebApi, SQL, or a NoSQL solution as in the following code:

public class TransitStopRepository { private readonly IList<TransitStop> _data = new List<TransitStop>(); /// <summary> /// Initializes a new instance of the <see cref="DataRepository"/> class. /// </summary> public TransitStopRepository() { Populate(); } /// <summary> /// Populates this instance. /// </summary> private void Populate() { var transitStop = new TransitStop { StationName = "Tsim Sha Tsui", UniqueNumber = 123, Location = new GeoLocation(114.171575, 22.293314), Buses = GenerateTSTBuses() }; _data.Add(transitStop); }

We are using an IList that contains all our transit data. The Populate method populates the list with all the information needed. It acts like a database containing all the TransitStop information. The following code interprets the same:

/// <summary> /// Generates the TST KMB buses. /// </summary> /// <returns></returns> private IEnumerable<Transit> GenerateTSTBuses() { var buses = new List<Transit> { new Transit { Number = "23A", ArrivalTimes = GenerateTimeTable(DateTime.Now), TransitColor = "Green" }, new Transit { Number = "23B", ArrivalTimes = GenerateTimeTable(DateTime.Now), TransitColor = "Yellow" } }; return buses; }

We use the GenerateTSTBuses method to generate two transit routes that will be arriving at the transit stop. It will also generate a timetable for the transits arriving at the transit stop for our in-memory database so that our domain objects will be fully populated when we send a query to them, as in the following code:

/// <summary> /// Generates a timetable with 2 minute apart arrival time. /// </summary> /// <param name="from">From.</param> /// <param name="incrementMinutes">The incrementMinutes.</param> /// <returns></returns> private IEnumerable<ArrivalTime> GenerateTimeTable(DateTime from) { //create a list var list = new List<ArrivalTime>(); var everyXminute = 2; //we will always generate 10 transits arriving to the stop for(var i = 0; i < 10; i++) { var arrivalTime = new ArrivalTime { Arrival = from.AddMinutes(everyXminutes) }; //double it for next everyXminutes *= 2; list.Add(arrivalTime); } return list; }

The GenerateTimeTable method generates the ArrivalTime object of the transit acting as a timetable for buses; we have hardcoded it to ten transits for our in-memory database, each arriving at an increment of 2 minutes apart.

Now that our repository has data fully populated, we can now use our repository to get fully populated domain objects. The following example uses the GetByUniqueNumber method to get a TransitStop object from the repository:

public static BusStopViewModel GetTransitStop(int uniqueNumber) { var repo = new TransitStopRepository(); var tStop = repo.GetByUniqueNumber(uniqueNumber); //create the map from -> to object AutoMapper.Mapper.CreateMap<TransitStop, BusStopViewModel>();

We then create the declaration of our mapping of the domain object to ViewModel by calling CreateMap, where AutoMapper will automatically map the objects that have the same naming convention. The step of creating a map is essential to AutoMapper your doing so tells AutoMapper what to map and what not to map.

Step 3 – mapping the object

The mapping is done by calling the Map method in AutoMapper and passing the data to map from. In the preceding example, the tStop variable contains data that we will be passing into for AutoMapper. By calling the Map method, we are essentially requesting AutoMapper to create another object based on the data we have provided, as illustrated in the following code:

//map the object var result = AutoMapper.Mapper.Map<TransitStop,
BusStopViewModel>(tStop); return result; }

In the preceding code, we are requesting AutoMapper to map the TransitStop object into BusStopViewModel object.

Step 4 – not mapping certain data

Let’s assume that the Location object is a very computing-intense object that requires lots of memory and CPU, or that we wish to use some other means of finding geolocation from a service, such as Google or Bing Maps. We can request AutoMapper not to map the object for us in our CreateMap method by using its mapping expression method ForMember as follows:

AutoMapper.Mapper.CreateMap<TransitStop, BusStopViewModel>() .ForMember(dest => dest.Location, opt => opt.Ignore());

By providing the Ignore option in the ForMember method, AutoMapper will not map the Location object.

Summary

In this article, we saw how to install AutoMapper, how to create a sample project, and how to transform our domain objects to ViewModel objects.

Resources for Article :


Further resources on this subject:


LEAVE A REPLY

Please enter your comment!
Please enter your name here