Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make automapper cache the object if met more than once

Tags:

c#

automapper

Is there any way to make automapper do not clone the same object but rather use a single object if it is met more than once in hierarchy?

Basically, I have a big array of different objects, that all reference the same object. When I map this collection with AutoMapper, it produces an array of objects where each object references a new cloned object. All these cloned object are not equal by reference anymore. This ends up in an out of memory issue for me.

Is there a way to configure some kind of cache for AutoMapper?

I've tried .PreserveReferences() in AutoMapper config, but that didn't do what I want. I think this works only for circular references.

Update.

Code example I test .PreserveReferences() with.

        [TestMethod]
        public void TestMethod1()
        {
            Mapper.Initialize(cfg =>
            {
                cfg.CreateMap<A, MA>().PreserveReferences();
                cfg.CreateMap<B, MB>();
            });

            var b = new B();
            var a1 = new A() { Ref = b };
            var a2 = new A() { Ref = b };
            Assert.AreNotSame(a1, a2);
            Assert.AreSame(a1.Ref, a2.Ref);

            var ma1 = Mapper.Map<MA>(a1);
            var ma2 = Mapper.Map<MA>(a2);
            Assert.AreNotSame(ma1, ma2);
            Assert.AreSame(ma1.Ref, ma2.Ref); // This fails.
        }

        class A { public B Ref { get; set; } }
        class B { }

        class MA { public MB Ref { get; set; } }
        class MB { }
like image 676
Archeg Avatar asked Oct 30 '17 13:10

Archeg


1 Answers

The identity is preserved per Map call.

void Main()
{
    Mapper.Initialize(cfg =>
    {
        cfg.CreateMap<A, MA>().PreserveReferences();
        cfg.CreateMap<B, MB>().PreserveReferences();
    });

    var b = new B();
    var a1 = new A() { Ref = b };
    var a2 = new A() { Ref = b };

    var ma = Mapper.Map<MA[]>(new[]{a1, a2});
    (ma[0] == ma[1]).Dump();
    (ma[0].Ref == ma[1].Ref).Dump();
}

class A { public B Ref { get; set; } }
class B { }

class MA { public MB Ref { get; set; } }
class MB { }
like image 164
Lucian Bargaoanu Avatar answered Oct 13 '22 03:10

Lucian Bargaoanu