Allow mapping to and from nested properties
I wish we could map nested objects back and forth with AutoMapper.
Let's take the example from #14:
class User
{
public string $email;
}
class Order
{
public string $reference;
public User $customer;
}
class OrderDTO
{
public string $reference;
public string $customerEmail;
}
$customer = new User();
$customer->email = '[email protected]';
$source = new Order();
$source->reference = 'FAC9123';
$source->customer = $customer;
dump($autoMapper->map($source, OrderDTO::class));
// Will output:
//
// OrderDTO {#14 🔽
// +reference: "FAC9123"
// +customerEmail: null
// }
Map from Order to OrderDTO
To map data inside customerEmail, so far the only solution is to use a transformer:
class OrderDTO
{
public string $reference;
#[MapFrom(Order::class, transformer: "source.user.email")]
public string $customerEmail;
}
It's working but it's not very natural, a better DX would be:
class OrderDTO
{
public string $reference;
#[MapFrom(Order::class, property: "user.email")]
public string $customerEmail;
}
Map from OrderDTO to Order
The only way I found is to create a transformer and return a User object. Which is very problematic because sometimes, the User could have other values I don't want to lose.
class Order
{
public string $reference;
#[MapFrom(OrderDTO::class, transformer: [self, "mapUser"])
public User $customer;
public static function mapUser($val, $source) {
$user = new User();
$user->email = $source->customerEmail;
return $user;
}
}
A better DX would have been:
class OrderDTO
{
public string $reference;
#[MapFrom(Order::class, property: "user.email")]
#[MapTo(Order::class, property: "user.email")]
public string $customerEmail;
}
And if "User" is null, throw an exception. (End-user can use the "if" attribute option to prevent unwanted exceptions).
Which is very problematic because sometimes, the User could have other values I don't want to lose.
This is exactly why we don't provide this feature out of the box, we cannot make it work without the user doing something, which means we simply move the problem in another place but with more code and then more complexity.