1

Mapster seems to not know how to map a simple assignment

UPDATE 1:

I added a method Value() to get the value of the Guid, if instead of a method I use a property public Guid Value => _value the mapping works.

I have an Id class

public class Id
{
    private readonly Guid _value;

    public Id(Guid id)
    {
        _value = id;
    }
    
    public static implicit operator Id(Guid value)
    {
        return new Id(value);
    }
    
    public static implicit operator Guid(Id value)
    {
        return value._value;
    }

    public Guid Value() => _value;
}

I have 2 classes

public class C1
{
    public Guid Id { get; set; }
}

public class C2
{
    public Id Id { get; set; }
}

When trying to map them out of the box it just doesn't work, it calls the constructor of the Id class with an empty Guid. I wrote a simple program where the assignment works just fine

Any ideas how to make this work?


Guid aGuidValue = Guid.NewGuid();
Id anIdValue = aGuidValue;
Guid anotherGuidValue = anIdValue;
Console.WriteLine(aGuidValue.Equals(anotherGuidValue));

var c1 = new C1() {Id = aGuidValue};
var c2 = c1.Adapt<C2>();
Console.WriteLine(aGuidValue.Equals(c2.Id));
Console.WriteLine(aGuidValue);
Console.WriteLine(c1.Id);
Console.WriteLine(c2.Id.Value());

Output

True
False
d46f8d3a-f055-47c8-8f03-17b4ae51a3a9
d46f8d3a-f055-47c8-8f03-17b4ae51a3a9
00000000-0000-0000-0000-000000000000

Up

dariogriffo
  • 4,148
  • 3
  • 17
  • 34
  • "it calls the constructor of the Id class with an empty string" - that seems unlikely, given that `Id` doesn't *have* a constructor accepting a string. What exactly do you mean? – Jon Skeet Mar 29 '23 at 08:40
  • I meant Guid, fixed the question and improved the output and added more information. – dariogriffo Mar 29 '23 at 08:52

1 Answers1

0

I opened an issue.
Surprisingly the conversion works the other way around:

var guid = Guid.NewGuid();

var pocoWithGuid1 = new PocoWithGuid { Id = guid };
Console.WriteLine(pocoWithGuid1.Id);    // 9c29424a-3c7b-4982-b301-84cc7ac41bc6

// Guid to Id fail
var pocoWithId1 = pocoWithGuid1.Adapt<PocoWithId>();
Console.WriteLine(pocoWithId1.Id);      // 00000000-0000-0000-0000-000000000000

var pocoWithId2 = new PocoWithId { Id = new Id(guid) };
Console.WriteLine(pocoWithId2.Id);      // 9c29424a-3c7b-4982-b301-84cc7ac41bc6

// Id to Guid works
var pocoWithGuid2 = pocoWithId2.Adapt<PocoWithGuid>();
Console.WriteLine(pocoWithGuid2.Id);    // 9c29424a-3c7b-4982-b301-84cc7ac41bc6

public class Id
{
    private readonly Guid _guid;

    public Id(Guid id) => _guid = id;

    public static explicit operator Id(Guid value) => new(value);
    public static explicit operator Guid(Id value) => value._guid;

    public override string ToString() => _guid.ToString();
}

public class PocoWithGuid
{
    public Guid Id { get; init; }
}

public class PocoWithId
{
    public Id Id { get; init; }
}

Demo code available here.

Orace
  • 7,822
  • 30
  • 45