2

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

Jester1811
  • 23
  • 5

0 Answers0