MapsterMapper / Mapster

A fast, fun and stimulating object to object Mapper
MIT License
4.32k stars 329 forks source link

Unable to map struct from object in another object #615

Open jankoci91 opened 1 year ago

jankoci91 commented 1 year ago

Hi! Am I right that failing assert in this test means bug?

In version 6.5.1 it works fine.

using Microsoft.VisualStudio.TestTools.UnitTesting;
using Shouldly;

namespace Mapster.Tests
{
    [TestClass]
    public class WhenMappingStructInObject
    {
        class Destination
        {
            public TestStruct TestStruct { get; set; }
        }

        class SourceWithClass
        {
            public SourceWithStruct SourceWithStruct { get; set; }
        }

        class SourceWithStruct
        {
            public TestStruct TestStruct { get; set; }
        }

        struct TestStruct
        {
            public string Property { get; }

            public TestStruct(string property) : this()
            {
                Property = property;
            }
        }

        [TestMethod]
        public void TestMapping()
        {
            TypeAdapterConfig<SourceWithClass, Destination>
                .ForType()
                .Map(x => x.TestStruct, x => x.SourceWithStruct.TestStruct);

            var source = new SourceWithClass
            {
                SourceWithStruct = new SourceWithStruct
                {
                    TestStruct = new TestStruct("A")
                }
            };

            var destination = source.Adapt<Destination>();

            destination.TestStruct.Property.ShouldBe("A");
        }
    }
}
codelovercc commented 1 year ago

Any exception stack trace?

jankoci91 commented 1 year ago

There is no exception I'm aware of. Just null instead of "A" as result.

andrerav commented 1 year ago

@jankoci91 Which NuGet package version are you using?

jankoci91 commented 1 year ago

7.3.0 Sorry for missing info.

andrerav commented 1 year ago

@jankoci91 Can you try the latest prerelease package please?

jankoci91 commented 1 year ago

Done. Same result. Null instead of "A".

DocSvartz commented 1 year ago

Hello, This is another type of bug #537 . Struct is detected as Record in https://github.com/MapsterMapper/Mapster/blob/04ac871b55828c3909b6cee4764e6fab40db3983/src/Mapster/Utils/ReflectionUtils.cs#L161

andrerav commented 1 year ago

Thank you @jankoci91 and @DocSvartz. I ran a git bisect session using the test posted by @jankoci91 above, and ended up with https://github.com/MapsterMapper/Mapster/commit/773f64adac3925878c966990ef26d49290c9ba2a as the supposed culprit. Still trying to piece this together, but now we know which commit that introduced the problem that causes this test to fail.

andrerav commented 1 year ago

@DocSvartz I think you're spot on. IsRecordType() is detecting types as record when it should not.

DocSvartz commented 1 year ago

@andrerav I managed to make a partial fix. It seems that problems with collections #430 and modification by an Object of type #524 have a different reason for bug. This bug hit Fork and Clone config. There, too, instances are not created transparently. But based on tests, this behavior is legitimate.