In MapStruct 1.3.0.Final
, we have dependency injection via constructor. Documentation says:
The generated mapper will inject all classes defined in the uses attribute
(...)
For abstract classes or decorators, setter injection should be used.
I have the following example:
@Mapper
public abstract class VehicleMapper {
@Autowired
private CarMapper carMapper;
@Autowired
private BikeMapper bikeMapper;
@Override
public VehicleDTO toDto(final Vehicle source) {
if (source instanceof Car) {
return carMapper.toDto((Car) source);
} else if (source instanceof Bike) {
return bikeMapper.toDto((Bike) source);
} else {
throw new IllegalArgumentException();
}
}
(...)
So, in my case, it should look like this (componentModel
defined in maven):
@Mapper
public abstract class VehicleMapper {
private CarMapper carMapper;
private BikeMapper bikeMapper;
@Autowired
public void setCarMapper(final CarMapper carMapper) {
this.carMapper = carMapper;
}
@Autowired
public void setBikeMapper(final BikeMapper bikeMapper) {
this.bikeMapper = bikeMapper;
}
@Override
public VehicleDTO toDto(final Vehicle source) {
if (source instanceof Car) {
return carMapper.toDto((Car) source);
} else if (source instanceof Bike) {
return bikeMapper.toDto((Bike) source);
} else {
throw new IllegalArgumentException();
}
}
(...)
Question:
So, is it not possible to inject carMapper
and bikeMapper
via the constructor? Does injectionStrategy = CONSTRUCTOR
work only for classes declared in @Mapper(uses = {})
?
I think that injectionStrategy = CONSTRUCTOR
works on the interface that has the @Mapper
annotation. I don't think it works with abstract classes. I'm sure it will not work when you define your own fields (instance variables). How would MapStruct know what user defined fields to initialise in the constructor?