我试图避免在这种情况下使用我自己的工厂,但是我找不到用Guice做这个的方法,也许是因为我是新手使用guice;)
我有这个接口将类型E转换为D类:
public interface SerializationProvider<E extends ValueEntity, D extends ModelDTO> {
D serialize(E entity) throws MappingSerializationException;
}
现在使用Dozer和一些反射,我可以使用一个如下所示的唯一Default类来实现它:
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;
}
}
请注意,我注入了Mapper。
现在问题是如何绑定它以便根据不同的对E,D提供DefaultSerializationProvider的不同实例 我想要避免的是创建一堆子类,其唯一目的是定义泛型。
在纯Java中我知道我可以提供一个工厂来提供这样的实例,如:
public interface SerializationProviderFactory {
public <E extends ValueEntity, D extends ModelDTO> SerializationProvider<E,D> get(Class<E> entityType, Class<D> dtoType);
}
一个非常简单的实现方式是:
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);
}
}
现在问题是如何使用Guice实现这种工厂? 或者有更好的方法吗?
工厂的一个简单用例是:
public MessureUnitDTO serializeUnit(MessureUnit unit){
SerializationProviderFactory factory=DefaultSerializationProviderFactory.INSTANCE;
SerializationProvider<MessureUnit, MessureUnitDTO> provider=factory.get(MessureUnit.class, MessureUnitDTO.class);
return provider.serialize(unit);
}
提前致谢, 丹尼尔
答案 0 :(得分:2)
据我所知,没有办法将DefaultSerializationProvider
绑定到所有可能的类型参数。但是如果你可以枚举你需要转换的所有类型参数,你可以使用这样的绑定:
bind(new TypeLiteral<SerializationProvider<MessureUnit, MessureUnitDTO>>() {})
.toInstance(new DefaultSerializationProvider<MessureUnit, MessureUnitDTO>(MessureUnitDTO.class));
如果您愿意,可以通过在toInstance
中注入类型文字来避免使用DefaultSerializationProvider
:
@Inject public DefaultSerializationProvider(TypeLiteral<D> dtoType) {
this.dtoClass = (Class<D>) dtoType.getRawType();
}
然后你可以使用这样的绑定:
bind(new TypeLiteral<SerializationProvider<MessureUnit, MessureUnitDTO>>() {})
.to(new TypeLiteral<DefaultSerializationProvider<MessureUnit, MessureUnitDTO>>() {});
答案 1 :(得分:0)
您可以使用Key.get(TypeLiteral<T> typeLiteral>
来实现对实例的参数化绑定。
MyClass<MyType> myClassInstanceOfMyType = new MyClass<MyType>();
bind(Key.get(new TypeLiteral<MyClass<MyType>>(){})).toInstance(myClassInstanceOfMyType);
然后在构造函数或基于成员的注入中使用as:
class MyOtherClass {
@Inject
MyOtherClass(MyClass<MyType> myClass){}
//stuff
}
或
class MyOtherClass {
@Inject
MyClass<MyType> myClass;
}