I'm trying to map from one hierarchy to another. Both my parent classes are abstracts as I'd never need to instantiate them, only their children. I would like to use a single mapping config the constructor of each child rather than create mapping configs for every child individually but haven't been able to do it so far unless I put a default constructor in each child class. However, I'd rather not as I want my domain objects to be instantiated in a valid state. Does anyone know if this is possible with mapster?
Domain classes
public abstract class Parent
{
public string Name{ get; set;}
}
public class A : Parent
{
public string PropertyA { get; set;}
public A(string propertyA)
{
PropertyA = propertyA;
}
}
public class B : Parent
{
public string PropertyB { get; set;}
public B(string propertyB)
{
PropertyB = propertyB;
}
}
View Models
public abstract class ParentVM
{
public string Name { get; set;}
}
public class AVM : ParentVM
{
public string PropertyA { get; set;}
}
public class BVM : ParentVM
{
public string PropertyB { get; set;}
}
Mapping config
//Domain to VM mapper
config.NewConfig<Parent, ParentVM>
.Include<A, AVM>
.Include<B, BVM>
;
//VM to Domain mapper
config.NewConfig<ParentVM, Parent>
.Include<AV<, A>
.Include<BVM, B>
.Fork(config => config.ForType<AVM, A>.ConstructUsing(src => new A(src.PropertyA)))
.Fork(config => config.ForType<BVM, B>.ConstructUsing(src => new B(src.PropertyB)));
Unit Tests
[Fact]
private void DomainToVMMapper_ViewModelReturned()
{
//Arrange
string propertyA = "Test";
var a = new A(propertyA) { Name = "Name" };
//Act
var aVM = _mapper.Map<Parent, ParentViewModel>(a);
//Assert
Assert.True(aVM is AVM); //this passes fine. I get a view model of A back
}
[Fact]
private void VMtoDomainMapper_VMReturned()
{
//Arrange
var aVM = new A() { Name = "Name", PropertyA = "Test" };
//Act
var a = _mapper<ParentVM, Parent>(aVM); //fails here - cannot instantiate type: A
//Assert
Assert.True(a is A)
}
Is there a way of passing multiple forked configs to the same mapper? Or am I going about this the wrong way? What I want to avoid is having to create a mapping config for each derived type & from/to combination and just throw a child object at a mapper based on the parent classes and the mapping knows what to do with it. And ideally by not using a default constructor. If I have to use a default constructor, what's the best way of making sure my domain model is in a valid state?
Thanks