-
Notifications
You must be signed in to change notification settings - Fork 378
Open
Labels
Description
Hello,
I have an issue with Mapster when using the MapToConstructor functionality.
If I have a ctor parameter that has an abstract type, and that parameter is null I get the following exception:
System.InvalidOperationException : Cannot instantiate type: AbstractDomainTestClass
I think Mapster should be able to handle null values in ctors for abstract types.
The following code showcases the issue:
using Mapster;
using MapsterMapper;
using NUnit.Framework;
public class MapsterCtorTests
{
private Mapper _mapper;
[SetUp]
public void Setup()
{
_mapper = new Mapper();
_mapper.Config.Default.MapToConstructor(true);
_mapper.Config.NewConfig<AbstractDtoTestClass, AbstractDomainTestClass>()
.Include<DerivedDtoTestClass, DerivedDomainTestClass>();
}
[Test(Description = "This works as expected")]
public void Dto_To_Domain_MapsCorrectly()
{
var dtoDerived = new DerivedDtoTestClass
{
DerivedProperty = "DerivedValue",
AbstractProperty = "AbstractValue"
};
var dto = new DtoTestClass
{
AbstractType = dtoDerived
};
var domain = dto.Adapt<DomainTestClass>();
Assert.Multiple(() =>
{
Assert.That(domain.AbstractType, Is.Not.Null, "Abstract type not mapped correctly");
Assert.That(domain.AbstractType, Is.TypeOf<DerivedDomainTestClass>(), "Abstract type not mapped correctly");
var domainDerived = (DerivedDomainTestClass)domain.AbstractType;
Assert.That(domainDerived.DerivedProperty, Is.EqualTo(dtoDerived.DerivedProperty), "Derived property not mapped correctly");
Assert.That(domainDerived.AbstractProperty, Is.EqualTo(dtoDerived.AbstractProperty), "Abstract property not mapped correctly");
});
}
[Test(Description = "This does not work, Mapster throws a InvalidOperationException with the following message: Cannot instantiate type: AbstractDomainTestClass")]
public void Dto_To_Domain_AbstractClassNull_MapsCorrectly()
{
var dto = new DtoTestClass
{
AbstractType = null
};
var domain = dto.Adapt<DomainTestClass>();
Assert.That(domain.AbstractType, Is.Null, "Abstract type not mapped correctly");
}
#region Immutable classes with private setters, map via ctors
private abstract class AbstractDomainTestClass
{
public string AbstractProperty { get; private set; }
protected AbstractDomainTestClass(string abstractProperty)
{
AbstractProperty = abstractProperty;
}
}
private class DerivedDomainTestClass : AbstractDomainTestClass
{
public string DerivedProperty { get; private set; }
/// <inheritdoc />
public DerivedDomainTestClass(string abstractProperty, string derivedProperty)
: base(abstractProperty)
{
DerivedProperty = derivedProperty;
}
}
private class DomainTestClass
{
public AbstractDomainTestClass AbstractType { get; private set; }
public DomainTestClass(
AbstractDomainTestClass abstractType)
{
AbstractType = abstractType;
}
}
#endregion
#region DTO classes
private abstract class AbstractDtoTestClass
{
public string AbstractProperty { get; set; }
}
private class DerivedDtoTestClass : AbstractDtoTestClass
{
public string DerivedProperty { get; set; }
}
private class DtoTestClass
{
public AbstractDtoTestClass AbstractType { get; set; }
}
#endregion
}