2013-12-17 2 views
2

У меня есть список экземпляров разных классов, и я хочу связать каждую из них только с собственным классом. Я пробовал цикл foreach с binder.bind(obj.getClass()).toInstance(obj), но, конечно, это не компилируется, потому что компилятор не в состоянии разрешить общий T. . Как еще это может быть достигнуто?Bind Class <?> с Guice

+1

Это очень вероятно, что вы делаете что-то неправильно. Если ваш список экземпляров статически известен, вы должны выполнить несколько вызовов 'bind(). ToInstance()' для каждого класса. Если этот список неизвестен заранее, вы должны действительно пересмотреть свой дизайн. Предполагается, что Guice не должен так использовать. Посмотрите на [multibindings] (http://code.google.com/p/google-guice/wiki/Multibindings), возможно, это то, что вам нужно. –

ответ

5

Все, что вам нужно, это отливка в сырой тип. Как и в комментарии chooks ниже (спасибо!), Guice эффективно действует как карта от ключевого (часто объект класса) до значения (поставщик этого класса), а дженерики просто помогают сохранить здравый смысл. Если вы уверены, что ваши ключевые матчи, вы можете переопределить дженерики, как это:

@Override 
protected void configure() { 
    for (Object object : getYourListOfInitializedObjects()) { 
    bindObjectAsSingleton(object); 
    } 
} 

/** Suppress warnings to convince the Java compiler to allow the cast. */ 
@SuppressWarnings({"unchecked", "rawtypes"}) 
private void bindObjectAsSingleton(Object object) { 
    bind((Class) object.getClass()).toInstance(object); 
} 

Как Vladimir упоминалось выше, это, как правило, не поощрять хороший дизайн Guice, потому что даже если у вас есть ваши DependencyImpl реализовать Dependency, в выше, создаст привязку только к DependencyImpl. Кроме того, все классы в вашем списке инициализированных синглетов должны создаваться без использования самой инъекции Guice, поэтому вы ограничиваете себя теми классами, которые вы инициализировали извне без помощи Guice. Вы можете использовать шаблон выше, если вы переходите от прежних версий «груду одиночек» в Guice, но вы, вероятно, получите дальше, если вы структурировать configure метод, как это как можно скорее:

@Override 
public void configure() { 
    // Let Guice create DependencyOne once, with injection, 
    // immediately on injector creation. 
    bind(DependencyOne.class).asEagerSingleton(); 

    // Let Guice create DependencyTwo once, with injection, 
    // but this way you can hopefully rely on interface DependencyTwo 
    // rather than concrete implementation DependencyTwoImpl. 
    bind(DependencyTwo.class).to(DependencyTwoImpl.class).asEagerSingleton(); 

    // Bind DependencyThree to an instance. Instance bindings are 
    // implicitly singletons, because you haven't told Guice how to 
    // create another one. 
    bind(DependencyThree.class).toInstance(getDependencyThreeInstance()); 

    // ...and so forth for everything in your list. 
} 
+2

Это хороший ответ. Чтобы добавить немного значения в OP - если вы читаете, как guice хранит привязки с внутренним значением ключа, это может немного упростить работу с дженериками. Я знаю, что у меня были проблемы с концептуальным сдвигом с моим кодом (который использовал много параметризованных типов/методов/и т. Д.) И, наконец, понимание механизма привязки значительно упростило ситуацию для решения проблем, связанных с дженериками и использованием вещей как TypeLiterals. – chooks

Смежные вопросы