Skip to content

Commit 155a723

Browse files
authored
Merge pull request #758 from DocSvartz/fix-interfaces-map-regression
Fix issue #755 - revert to behavior from 7.4.0 and new features
2 parents 44b078c + b9d403f commit 155a723

File tree

2 files changed

+204
-1
lines changed

2 files changed

+204
-1
lines changed

src/Mapster.Tests/WhenMappingRecordRegression.cs

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,83 @@ public void MultiCtorAndInlineRecordWorked()
278278
}
279279

280280

281+
[TestMethod]
282+
public void MappingInterfaceToInterface()
283+
{
284+
TypeAdapterConfig<IActivityData, IActivityDataExtentions>
285+
.ForType()
286+
.Map(dest => dest.TempLength, src => src.Temp.Length);
287+
288+
289+
var sourceBase = new SampleInterfaceClsBase
290+
{
291+
ActivityData = new SampleActivityData
292+
{
293+
Data = new SampleActivityParsedData
294+
{
295+
Steps = new List<string> { "A", "B", "C" }
296+
},
297+
Temp = "Temp data"
298+
299+
}
300+
301+
};
302+
var sourceDerived = new SampleInterfaceClsDerived
303+
{
304+
ActivityData = new SampleActivityData
305+
{
306+
Data = new SampleActivityParsedData
307+
{
308+
Steps = new List<string> { "X", "Y", "Z" }
309+
},
310+
Temp = "Update Temp data"
311+
312+
}
313+
314+
};
315+
316+
var sourceExt = new SampleInterfaceClsExtentions
317+
{
318+
ActivityData = new SampleActivityDataExtentions
319+
{
320+
Data = new SampleActivityParsedData
321+
{
322+
Steps = new List<string> { "o", "o", "o" }
323+
},
324+
Temp = "Extentions data",
325+
TempLength = "Extentions data".Length
326+
327+
}
328+
329+
};
330+
331+
var TargetBase = sourceBase.Adapt<SampleInterfaceClsBase>();
332+
var targetDerived = sourceDerived.Adapt<SampleInterfaceClsDerived>();
333+
var update = targetDerived.Adapt(TargetBase);
334+
335+
var targetExtention = sourceExt.Adapt<SampleInterfaceClsExtentions>();
336+
337+
338+
var updExt = targetDerived.Adapt(targetExtention);
339+
340+
targetDerived.ShouldNotBeNull();
341+
targetDerived.ShouldSatisfyAllConditions(
342+
() => targetDerived.ActivityData.ShouldBe(sourceDerived.ActivityData),
343+
() => update.ActivityData.ShouldBe(targetDerived.ActivityData),
344+
345+
()=> updExt.ActivityData.ShouldBe(targetExtention.ActivityData),
346+
() => ((SampleActivityDataExtentions)updExt.ActivityData).Temp.ShouldBe(sourceDerived.ActivityData.Temp),
347+
() => ((SampleActivityDataExtentions)updExt.ActivityData).TempLength.ShouldBe(sourceDerived.ActivityData.Temp.Length),
348+
// IActivityData interface and all its derivatives do not provide access to the Data property for all implementations of the SampleActivityData class,
349+
// so this property will not be changed by mapping
350+
() => ((SampleActivityDataExtentions)updExt.ActivityData).Data.ShouldBe(((SampleActivityDataExtentions)targetExtention.ActivityData).Data)
351+
352+
);
353+
354+
}
355+
356+
357+
281358
#region NowNotWorking
282359

283360
/// <summary>
@@ -305,6 +382,104 @@ public void CollectionUpdate()
305382

306383
#region TestClasses
307384

385+
public interface IActivityDataExtentions : IActivityData
386+
{
387+
public int TempLength { get; set; }
388+
}
389+
390+
public interface IActivityData : IActivityDataBase
391+
{
392+
public string Temp { get; set; }
393+
}
394+
395+
public interface IActivityDataBase
396+
{
397+
398+
}
399+
400+
401+
public class SampleInterfaceClsExtentions
402+
{
403+
public IActivityDataExtentions? ActivityData { get; set; }
404+
405+
public SampleInterfaceClsExtentions()
406+
{
407+
408+
}
409+
410+
public SampleInterfaceClsExtentions(IActivityDataExtentions data)
411+
{
412+
SetActivityData(data);
413+
}
414+
415+
public void SetActivityData(IActivityDataExtentions data)
416+
{
417+
ActivityData = data;
418+
}
419+
}
420+
421+
422+
423+
public class SampleInterfaceClsBase
424+
{
425+
public IActivityDataBase? ActivityData { get; set; }
426+
427+
public SampleInterfaceClsBase()
428+
{
429+
430+
}
431+
432+
public SampleInterfaceClsBase(IActivityDataBase data)
433+
{
434+
SetActivityData(data);
435+
}
436+
437+
public void SetActivityData(IActivityDataBase data)
438+
{
439+
ActivityData = data;
440+
}
441+
}
442+
443+
public class SampleInterfaceClsDerived
444+
{
445+
public IActivityData? ActivityData { get; set; }
446+
447+
public SampleInterfaceClsDerived()
448+
{
449+
450+
}
451+
452+
public SampleInterfaceClsDerived(IActivityData data)
453+
{
454+
SetActivityData(data);
455+
}
456+
457+
public void SetActivityData(IActivityData data)
458+
{
459+
ActivityData = data;
460+
}
461+
}
462+
463+
public class SampleActivityDataExtentions : IActivityDataExtentions
464+
{
465+
public SampleActivityParsedData Data { get; set; }
466+
public string Temp { get; set; }
467+
public int TempLength { get; set; }
468+
}
469+
470+
public class SampleActivityData : IActivityData
471+
{
472+
public SampleActivityParsedData Data { get; set; }
473+
public string Temp { get; set; }
474+
}
475+
476+
public class SampleActivityParsedData
477+
{
478+
public List<string> Steps { get; set; } = new List<string>();
479+
}
480+
481+
482+
308483
class MultiCtorAndInlinePoco
309484
{
310485
public int MyInt { get; set; }
@@ -499,5 +674,14 @@ sealed record TestSealedRecord()
499674

500675
sealed record TestSealedRecordPositional(int X);
501676

677+
678+
679+
680+
681+
682+
683+
684+
685+
502686
#endregion TestClasses
503687
}

src/Mapster/Adapters/ReadOnlyInterfaceAdapter.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ internal class ReadOnlyInterfaceAdapter : ClassAdapter
1010

1111
protected override bool CanMap(PreCompileArgument arg)
1212
{
13-
return arg.DestinationType.IsInterface && arg.DestinationType.GetProperties().Length > 0;
13+
return arg.DestinationType.IsInterface;
1414
}
1515

1616
protected override bool CanInline(Expression source, Expression? destination, CompileArgument arg)
@@ -45,5 +45,24 @@ protected override Expression CreateInstantiationExpression(Expression source, E
4545
return base.CreateInstantiationExpression(source,destination, arg);
4646
}
4747

48+
protected override Expression CreateExpressionBody(Expression source, Expression? destination, CompileArgument arg)
49+
{
50+
if (source.Type.IsInterface)
51+
{
52+
if (!arg.DestinationType.IsAssignableFrom(arg.SourceType))
53+
return base.CreateExpressionBody(source, destination, arg);
54+
55+
if (arg.MapType != MapType.MapToTarget)
56+
return Expression.Convert(source, arg.DestinationType);
57+
58+
if (arg.MapType == MapType.MapToTarget)
59+
return source;
60+
61+
return base.CreateExpressionBody(source, destination, arg);
62+
}
63+
64+
return base.CreateExpressionBody(source, destination, arg);
65+
}
66+
4867
}
4968
}

0 commit comments

Comments
 (0)