2013-07-19 35 views
2

一个泛型工厂我已经写了能够创建任何类型的ListEditor工厂:使用GIN注入的ListEditor

public interface ListEditorFactory<T, E extends Editor<T>> { 
    ListEditor<T, E> create(InsertPanel panel); 
} 

及其实施:

public class ListEditorFactoryImpl<T, E extends Editor<T> & IsWidget> implements ListEditorFactory<T, E> { 
    private final Provider<E> editorProvider; 

    @Inject 
    public ListEditorFactoryImpl(Provider<E> editorProvider) { 
     this.editorProvider = editorProvider; 
    } 

    @Override 
    public ListEditor<T, E> create(final InsertPanel panel) { 
     return ListEditor.of(new EditorSource<E>() { 
      @Override 
      public E create(int index) { 
       final E e = editorProvider.get(); 
       panel.add(e.asWidget()); 
       return e; 
      } 

      @Override 
      public void dispose(E e) { 
       e.asWidget().removeFromParent(); 
      } 

      @Override 
      public void setIndex(E editor, int index) { 
       panel.insert(editor.asWidget(), index); 
      } 
     }); 
    } 
} 

它非常好,如果我直接实例化一个提供者注入由杜松子酒厂:

ListEditor<NoteDTO, CharacterNoteScreen> notesEditor; 
@Inject @UiField(provided = true) FlowPanel notePanel; 

@Inject 
protected void init(Provider<CharacterNoteScreen> characterNoteProvider) { 
    final ListEditorFactory<NoteDTO, CharacterNoteScreen> listEditorFactory = new ListEditorFactoryImpl<NoteDTO, CharacterNoteScreen>(characterNoteProvider); 
    notesEditor = listEditorFactory.create(notePanel); 

但如果我想注入整个ListEditorFac保守党是这样的:

@Inject 
protected void init(ListEditorFactory<NoteDTO, CharacterNoteScreen> listEditorFactory) { 
    notesEditor = listEditorFactory.create(notePanel); 

杜松子酒抱怨用一个简单的bind(ListEditorFactory.class).to(ListEditorFactoryImpl.class);结合:

[ERROR] Generator 'com.google.gwt.inject.rebind.GinjectorGenerator' threw an exception while rebinding 'net.test.client.MyGinjector' 
com.google.inject.ConfigurationException: Guice configuration errors: 
1) javax.inject.Provider<E> cannot be used as a key; It is not fully specified. 

我试着用bind(new TypeLiteral<ListEditorFactory<?, ?>>() {}).to(new TypeLiteral<ListEditorFactoryImpl<?, ?>>() {});但有一个

java.lang.IllegalArgumentException: Expected a Class, ParameterizedType, or GenericArrayType, but <?> is of type com.google.inject.internal.MoreTypes$WildcardTypeImpl 

结合bind(new TypeLiteral<ListEditorFactory<NoteDTO, CharacterNoteScreen>>() {}).to(new TypeLiteral<ListEditorFactoryImpl<NoteDTO, CharacterNoteScreen>>() {});是工作,但通用的工厂损失它的很多兴趣。

你知道一个通​​用的方式来声明这种绑定?

感谢

回答

1

我设法摆脱ListEditorFactory接口的找到解决的办法,不再需要声明杜松子酒模块中结合。

我可以直接注入实现没有任何问题:

@Inject 
protected void init(ListEditorFactoryImpl<NoteDTO, CharacterNoteScreen> listEditorFactory) { 
    notesEditor = listEditorFactory.create(notePanel); 

如果杜松子酒是能够注入这一点,我认为没有理由不能把它注射槽的接口,但错误的绑定声明。

所以,即使我对我的解决方案感到满意,我也会让问题开放,因为它可能是一种声明绑定的方式。

+0

根据[与GIN注入类](http://stackoverflow.com/questions/7093274/inject-a-classt-with-gin)杜松子酒不能注入通配符类型的泛型,因为它完成所有在有效类型未知的编译时工作。我仍然不明白它是如何工作的,没有绑定声明,我想有同样的问题。无论如何,我接受这个答案,因为它似乎没有更好的解决方案。 – Arnor