Automapper extended use

What does Automapper do?


It saves you time mapping properties with same names and types, by doing that automatically for you. You just have to tell the library which class can me mapped to another and etc.
...

Adding the 'Automapper' nuget package is super easy, just find it and istall it. This is why you are probably thinking why is this even mentioned as a 'Feature' of the template, but there is more to it.
*These custom configurations are made for Automapper version 3.3.1, but might be refactored easy for the lattest versions

You can download the template with the implementation here!
We don't consider installing the nuget package as a feature but the follow up configurations of the mappings, without which usually the projects end up with a couple of huge files describing mappings between classes. This is exactly what we are preventing when adding additional configurations to it.

Lets see how can we do that.
We have to add AutomapperConfig class and couple of interfaces like IMapFrom and IHaveCustomMappings.

 public class AutoMapperConfig
    {
        public static void Execute()
        {
            var types = Assembly.GetExecutingAssembly().GetExportedTypes();

            LoadStandardMappings(types);

            LoadCustomMappings(types);
        }

        private static void LoadCustomMappings(IEnumerable types)
        {
            var maps = (from t in types
                        from i in t.GetInterfaces()
                        where typeof(IHaveCustomMappings).IsAssignableFrom(t) &&
                        !t.IsAbstract &&
                        !t.IsInterface
                        select (IHaveCustomMappings)Activator.CreateInstance(t)).ToArray();

            foreach (var map in maps)
            {
                map.CreateMappings(Mapper.Configuration);
            }
        }

        private static void LoadStandardMappings(IEnumerable types)
        {
            var maps = (from t in types
                        from i in t.GetInterfaces()
                        where i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom<>) &&
                        !t.IsAbstract &&
                        !t.IsInterface
                        select new
                        {
                            Source = i.GetGenericArguments()[0],
                            Destination = t
                        }).ToArray();

            foreach (var map in maps)
            {
                Mapper.CreateMap(map.Source, map.Destination);
                Mapper.CreateMap(map.Destination, map.Source);
            }
        }
    }

    public interface IHaveCustomMappings
    {
        void CreateMappings(IConfiguration configuration);
    }

     public interface IMapFrom
        where T : class
    {
    }

This method execute should be called on ApplicationStart in the Global.cs file.
What this source code gives us neatly and clean way to create mapping between the classes.

Here is an example of the creation of the mappings this way.

public class TSFeatureViewModel : BaseViewModel, IMapFrom, IHaveCustomMappings
{


        public string Name { get; set; }

        public string Description { get; set; }

        public string Link { get; set; }

        public string ImplementationDetails { get; set; }

        public decimal? AddedValue { get; set; }

        public string VideoUrl { get; set; }

        public int? ParentFeatureId { get; set; }

        public string ParentFeature { get; set; }

        public void CreateMappings(IConfiguration configuration)
        {
            configuration.CreateMap()
             .ForMember(m => m.ParentFeature, opt => opt.MapFrom(t => t.ParentFeature != null ? t.ParentFeature.Name : null))
             .ReverseMap();
        }
 }
When we implement the IMapFrom interface with generic argument of the source class we enable mappings between the properties with similar names and types.
In case that we have properties that are called differently we have the Ihavecustommappings interface which makes us implement a mehtod called CreateMappings and point out manually which property have to be mapped to which.

If you want to see the '3 minute' video about these configurations :

Download the template here!