Alternatives to AutoMapper [closed]
Asked Answered
D

6

78

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.

Dorolisa answered 13/8, 2011 at 17:6 Comment(1)
take a look at https://mcmap.net/q/126472/-automapper-vs-valueinjecter-closedKoheleth
B
39

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

Bertrambertrand answered 13/8, 2011 at 17:16 Comment(6)
Thanks for your great help. which one is recommended?Dorolisa
If performance is a consideration EmitMapper wins big time. Its perf as pretty close to handwritten conversion code.Gibbsite
ValueInjecter last version in 2011/feb, EmitMapper last version in 2010/Jan - that is kind of point of concern I think.Paeon
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.Emelina
as of 2015 there is a pretty cool new kid on the block: expressmapper.orgLieberman
A very good tool MappingGenerator with a free version - never again magic behind your back: github.com/cezarypiatek/MappingGenerator or mappinggenerator.netDombrowski
S
34

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.

Schooner answered 19/8, 2014 at 23:38 Comment(1)
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!Actinomycin
J
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

Jerri answered 1/10, 2011 at 19:38 Comment(0)
H
5

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

Hirsutism answered 28/10, 2017 at 16:18 Comment(0)
R
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;
    }
Receptacle answered 4/6, 2016 at 16:44 Comment(4)
This is too limited to ever be a real alternative.Sadirah
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.Artur
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.Lexington
what does this mean? "classes will need to have a parameterless constructor 'where TResult : new()' "Attendance
M
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.

Moorings answered 12/11, 2016 at 9:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.