76

What are the different alternative frameworks available for object to object mapping in .NET apart from AutoMapper

Currently we're planning to use AutoMapper, but before finalizing this framework, we want to understand any other frameworks are out there.

Tim Lloyd
  • 37,954
  • 10
  • 100
  • 130
subramn
  • 911
  • 1
  • 8
  • 13

6 Answers6

40

EmitMapper, http://emitmapper.codeplex.com/

ValueInjecter https://github.com/omuleanu/ValueInjecter

BLToolkit https://github.com/igor-tkachev/bltoolkit

And my homework development OoMapper https://github.com/hazzik/OoMapper

hazzik
  • 13,019
  • 9
  • 47
  • 86
  • 2
    Thanks for your great help. which one is recommended? – subramn Aug 13 '11 at 17:47
  • 4
    If performance is a consideration EmitMapper wins big time. Its perf as pretty close to handwritten conversion code. – Shreedhar Kotekar Mar 21 '12 at 15:15
  • 10
    ValueInjecter last version in 2011/feb, EmitMapper last version in 2010/Jan - that is kind of point of concern I think. – Giedrius Aug 08 '13 at 09:32
  • 4
    ValueInjecter's latest version is now October 2015; way newer than EmitMapper whose last release date is still January 2010. Just figured I'd put this here for any lurkers. – KSwift87 Jan 14 '16 at 17:27
  • 2
    as of 2015 there is a pretty cool new kid on the block: http://www.expressmapper.org/ – bbqchickenrobot Jan 10 '17 at 00:55
  • A very good tool **MappingGenerator** with a free version - never again magic behind your back: https://github.com/cezarypiatek/MappingGenerator or https://mappinggenerator.net/ – Jerzy Gebler Feb 27 '23 at 07:08
31

Old question, but take a look at Mapster. It's a lot faster than AutoMapper (5-10X in the scenarios I've used it in) if performance is critical and supports most AutoMapper scenarios. Always remember to perf test as results vary by scenario.
We've dropped a new 3.x version that works for .Net 4.0/4.5/Core, supports several new features, and has big perf improvements.

http://www.nuget.org/packages/Mapster/

https://github.com/eswann/Mapster

Disclosure...it's one of my projects that was created for a high load service where AutoMapper started showing up as one of our bottlenecks.

swannee
  • 3,346
  • 2
  • 24
  • 40
  • 6
    You may be interested to know that there is now a Mapster tag for SO. You may want to subscribe to it so you can get alerted to new questions! – tom redfern Nov 30 '16 at 15:52
18

I went through a similar process recently trying to find a mapper that really covers all my scenarios as well. I've found ValueInjecter the best out of the automapper, emitmapper, and a few others on codeplex.

I choose ValueInjector because it's the most flexible of them all. I had a requirement to map from entity to viewmodel, and viewmodel back to entity, deep cloning where you have customer -> projects -> project, recursive situations like customer <-> project, and add/update/delete of children collections.

Out of the box ValueInjector doesn't support this, but it's framework is extensible enough to support this easily. You can see my extension point in this convention I posted on their discussion forum...

http://valueinjecter.codeplex.com/discussions/274484

kinstephen
  • 721
  • 5
  • 8
5

This is an old question, but there's now also https://github.com/agileobjects/AgileMapper

Malcolm
  • 1,239
  • 1
  • 14
  • 25
2

If you would prefer to "roll your own" ... Here is a Quick n dirty alternative to AutoMapper (bit easier to debug issues + 1 less project dependency)

    public static List<TResult> QuickMapper<TSource, TResult>(IList<TSource> data) where TResult : new()
    {
        /*


         N.B. no DEEP copy - good for simple dto to View Model transfer etc ...
         classes will need to have a parameterless constructor  'where TResult : new()' 
         by default - this will ignore cases where destination object does not have one of the source object's fields- common in ViewModels ...
         you could use a Dictionary<String,string> param to handle cases  where property names don't marry up..

        to use :   List<Class2> lst2 = Helper.QuickMapper<Class1, Class2>(lst1).ToList();

        */

        var result = new List<TResult>(data.Count);


        PropertyDescriptorCollection propsSource = TypeDescriptor.GetProperties(typeof(TSource));
        PropertyDescriptorCollection propsResult= TypeDescriptor.GetProperties(typeof(TResult));


        TResult obj;
        Object colVal;
        string sResultFieldName = "";
        string sSourceFieldName = "";

        foreach (TSource item in data)
        {
            obj = new TResult();

            for (int iResult = 0; iResult < propsResult.Count; iResult++)
            {
                PropertyDescriptor propResult = propsResult[iResult];
               sResultFieldName = propResult.Name ;

               for (int iSource = 0; iSource < propsResult.Count; iSource++)
                {
                  PropertyDescriptor propSource  = propsSource [iSource ];

                   sSourceFieldName = propSource.Name; 

                    if (sResultFieldName == sSourceFieldName)
                    {
                        try
                        {
                            colVal = propSource.GetValue(item) ?? null;
                            propResult.SetValue(obj, colVal);
                        }
                        catch (Exception ex)
                        {
                            string ss = "sResultFieldName = " + sResultFieldName + "\r\nsSourceFieldName = " + sSourceFieldName + "\r\n" + ex.Message + "\r\n" + ex.StackTrace;
                            // do what you want here ...
                        }
                    }
                }

            }

            result.Add(obj);
        }
        return result;
    }
cSharpGuy
  • 29
  • 2
  • 3
    This is too limited to ever be a real alternative. – Gert Arnold Jun 04 '16 at 19:05
  • 2
    That's the naive approach, giving you the worst possible performance combined with the worst possible flexibility. If you want to keep it simple and as fast as possible, use hand written mapping code. This also gives you maximum flexibility. Otherwise, use one of the well-tested, highly optimized and flexible mapping tools that are already out there. A hand-rolled basic reflection based generic mapper is pretty much the worst possible solution. – chris Jul 24 '16 at 14:32
  • Nowadays all you hear is package names being thrown around. Sometimes you only need 10% of what the package has to offer and developers still download the whole package which could be bigger than the whole solution. This way you don't have to wait for packages to be updated in case it has an issue and you don't have to worry about your code breaking on the next update (I know you can fix it as it is open source but its still more time consuming) which translates to better flexibility. I voted this up because it might be the best answer for someone that needs limited mapping. – DonO Sep 30 '16 at 20:24
  • what does this mean? "classes will need to have a parameterless constructor 'where TResult : new()' " – redwards510 Dec 07 '16 at 00:29
0

Why not using such tools even if you just need 10% of its functionalities. Those tools are usually well tested and with practice, we like to use them more and more, and then we start using their other fancy possibilities. Upgrading the product is always risky, but that is what the unit tests are for.
Also, I discovered a new mapper that seems promising : Hmapper. I specially like its performance, its ability to choose what sub objects must be retrieved during mapping, and its strongly typed way of mapping open generic types. This mapper works well so far, at least in my current project. Have a look here :

http://www.codeproject.com/Tips/1152752/H-Mapper

For example, we can specify sub objects using Linq:

Mapper.Map<Class1, Class2>(source, x=>x.Subobject)

This way, we don't have to create a DTO class for detailed information and another one for listing (light weight).

I find this very neat.

Seblac
  • 1