fluentsprings / ExpressMapper

Mapping .Net types
http://www.expressmapper.org
Other
310 stars 65 forks source link

Merge objects similarly to JS spread operator #160

Open artemiusgreat opened 1 year ago

artemiusgreat commented 1 year ago

Is it possible to merge two objects in a way that properties will be copied from source to destination only if in the source they are not NULL? Using JavaScript syntax for spread ... operator or Object.assign() method as an example.

var source = { Name: "X", Items: [ 1, 2, 3, 4, 5 ] }
var destination = { Name: "X", Items: [ 1, 2, 3, 4, 5 ], Count: 5 }

var res1 = { ...destination, ...source }
var res2 = Object.assign(destination, source)

res1 == res2 // True

I was able to achieve similar functionality with Automapper by checking, if the relevant property in the source is NULL, then do not override it in the destination.

var setup = new MapperConfiguration(expression =>
{
  expression
    .CreateMap<DemoModel, DemoModel>()
    .ForAllMembers(o => o.Condition((x, y, memberX, memberY) => memberX is not null));
};

var mapper = setup.CreateMapper();
var source = new DemoModel { Name: "X"};
var destination = new DemoModel { Name: "Y", Items: new[] { 1, 2, 3 }};
var res = mapper.Map(source, destination);

// Expected result is { Name: "X", Items: new[] { 1, 2, 3 }} so only Name property got overridden

Unfortunately, Automapper implements some ridiculously horrible behavior by clearing collections even when they're not supposed to be touched.

Question

Is merging, aka overriding only specific properties, possible in mapper without breaking collections?