I was trying to avoid using my own factory in this case, but I couldn't found a way of doing this with Guice, maybe because I'm new using guice ;)
I have this interface to convert type E into type D :
public interface SerializationProvider<E extends ValueEntity, D extends ModelDTO> {
D serialize(E entity) throws MappingSerializationException;
}
Now using Dozer and a bit of reflection, I could implement this with a unique Default class that looks like this:
public class DefaultSerializationProvider<E extends ValueEntity, D extends ModelDTO> implements
SerializationProvider<E, D> {
private Mapper mapper;
private Class<D> dtoClass;
@Inject
public DefaultSerializationProvider(Class<D> dtoClass){
this.dtoClass=dtoClass;
}
@Override
public D serialize(E entity) throws MappingSerializationException {
D result=this.getNewDTOInstance();
this.mapper.map(entity, result);
return result;
}
protected D getNewDTOInstance() throws MappingSerializationException {
try{
D result=this.dtoClass.newInstance();
return result;
}catch(InvocationException ie){
throw new MappingSerializationException(ie);
}catch(IllegalAccessException iae){
throw new MappingSerializationException(iae);
}catch(InstantiationException iie){
throw new MappingSerializationException(iie);
}
}
@Inject
public void setMapper(Mapper mapper) {
this.mapper = mapper;
}
}
Note that I inject the Mapper.
Now the question is how can I bind this in order to provides different instances of the DefaultSerializationProvider depending on different pairs E,D What I want to avoid is creating the hole bunch of subclasses with the sole purpose of defining the generics.
In pure Java I know I can provide a Factory that will provides this kind of instances like:
public interface SerializationProviderFactory {
public <E extends ValueEntity, D extends ModelDTO> SerializationProvider<E,D> get(Class<E> entityType, Class<D> dtoType);
}
A very simple implementation of this will be:
public class DefaultSerializationProviderFactory implements
SerializationProviderFactory {
public static final DefaultSerializationProviderFactory INSTANCE=new DefaultSerializationProviderFactory();
@Override
public <E extends ValueEntity, D extends ModelDTO> SerializationProvider<E, D> get(
Class<E> entityType, Class<D> dtoType) {
return new DefaultSerializationProvider<E, D>(dtoType);
}
}
Now the question is how can I implement this kind of Factory using Guice? Or are there a better way of doing this?
A simple use case of the Factory will be:
public MessureUnitDTO serializeUnit(MessureUnit unit){
SerializationProviderFactory factory=DefaultSerializationProviderFactory.INSTANCE;
SerializationProvider<MessureUnit, MessureUnitDTO> provider=factory.get(MessureUnit.class, MessureUnitDTO.class);
return provider.serialize(unit);
}
Thanks in advance, Daniel
As far as I know there is no way to bind the
DefaultSerializationProvider
for all possible type arguments. But if you can enumerate all type arguments that you need to convert, you can use a binding like this:If you prefer, you can avoid using
toInstance
by injecting a type literal into theDefaultSerializationProvider
:Then you can use a binding like this: