UltraMapper icon indicating copy to clipboard operation
UltraMapper copied to clipboard

additional feature requested.

Open hermanlindner opened this issue 2 years ago • 1 comments

The feature that I have been missing from this library is the posibillity to conditionally skip a mapping. But not just in the converter part of the mapping, Instead To have the posibillity to not even access the skipped member on the original object tree.

My use case: Would like to be able to use ultramapper for mapping a source tree to a target tree. But the source tree is Lazy loaded tree made up by NHibernate. Accessing the members on the source tree does result in additional Database calls. And the goal in the mapping is to Prune too large object trees before serialization, but then without accessing the Source members to be skipped.

I implemented the change locally, to fix this. But somehow I am not authorized to connect my Visual studio to push my branch to github. Because I would like to push a pullrequest for this change.

Below is the test code I have using this feature:

using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Collections.Generic;

namespace UltraMapper.Tests { public class DoMap { private DoChildMap _nested; private List<DoChildMap> _children; private int _count; private int _collectionCount;

    public int NestedGetCount => _count;

    public bool UseNested { get; set; }

    public DoChildMap Nested
    {
        get
        {
            _count++;
            return _nested;
        }
        set => _nested = value;
    }

    public int NestedCollectionGetCount => _collectionCount;

    public bool UseNestedCollection { get; set; }

    public List<DoChildMap> NestedCollection
    {
        get
        {
            _collectionCount++;
            return _children;
        }
        set => _children = value;
    }
}

public class DoChildMap
{
    public string MyName { get; set; }
}

[TestClass]
public class ConditionalTests
{
    [TestMethod]
    public void ConditionalMapSkippedSourceProp()
    {
        var source = new DoMap()
        {
            UseNested = false,
            Nested = new DoChildMap()
            {
                MyName = "bla"
            }
        };
        var countBefore = source.NestedGetCount;
        var target = ConfiguredMapper.Map<DoMap, DoMap>( source );
        var countAfter = source.NestedGetCount;
        Assert.IsNotNull( source.Nested, "source" );
        Assert.IsNull( target.Nested, "target" );
        Assert.AreEqual( countBefore, countAfter );
    }

    [TestMethod]
    public void ConditionalMapNotSkippedSourceProp()
    {
        var source = new DoMap()
        {
            UseNested = true,
            Nested = new DoChildMap()
            {
                MyName = "bla"
            }
        };
        var countBefore = source.NestedGetCount;
        var target = ConfiguredMapper.Map<DoMap, DoMap>( source );
        var countAfter = source.NestedGetCount;
        Assert.IsNotNull( target.Nested, "target" );
        Assert.IsNotNull( source.Nested, "source" );
        Assert.AreEqual( countBefore + 1, countAfter );
    }

    [TestMethod]
    public void ConditionalCollectionMapSkippedSourceProp()
    {
        var source = new DoMap()
        {
            UseNested = false,
            Nested = new DoChildMap()
            {
                MyName = "bla"
            },
            UseNestedCollection = false,
            NestedCollection = new List<DoChildMap> {
                new DoChildMap() { MyName="kwuk1"} ,
                new DoChildMap() { MyName = "kwuk2" }
            }
        };
        var countBefore = source.NestedCollectionGetCount;
        var target = ConfiguredMapper.Map<DoMap, DoMap>( source );
        var countAfter = source.NestedCollectionGetCount;
        Assert.AreEqual( source.NestedCollection.Count, 2 );
        Assert.AreEqual( target.NestedCollection.Count, 0 );
        Assert.AreEqual( countBefore, countAfter );
    }

    [TestMethod]
    public void ConditionalCollectionMapNotSkippedSourceProp()
    {
        var source = new DoMap()
        {
            UseNested = false,
            Nested = new DoChildMap()
            {
                MyName = "bla"
            },
            UseNestedCollection = true,
            NestedCollection = new List<DoChildMap> {
                new DoChildMap() { MyName="kwuk1"} ,
                new DoChildMap() { MyName = "kwuk2" }
            }
        };
        var countBefore = source.NestedCollectionGetCount;
        var target = ConfiguredMapper.Map<DoMap, DoMap>( source );
        var countAfter = source.NestedCollectionGetCount;
        Assert.AreEqual( source.NestedCollection.Count, 2 );
        Assert.AreEqual( target.NestedCollection.Count, 2 );
        Assert.AreEqual( countBefore + 1, countAfter );
    }

    private Mapper ConfiguredMapper =>
         new Mapper( cfg =>
        {
            cfg.MapTypes<DoMap, DoMap>()
               .MapConditionalMember(
                    a => a.UseNested,
                    () => null,
                    a => a.Nested,
                    t => t.Nested
               )
               .MapConditionalMember(
                    a => a.UseNestedCollection,
                    () => new List<DoChildMap>(),
                    a => a.NestedCollection,
                    t => t.NestedCollection
               );
        } );
}

}

hermanlindner avatar Feb 25 '23 12:02 hermanlindner

By now I managed to create a Pullrequest for my changes

hermanlindner avatar Feb 25 '23 13:02 hermanlindner