dependency injection - marvel - Daga: ¿Inyectar cuerdas @Named?
daggerfragment (2)
Debe definir un proveedor en el módulo de daga para su instancia de @Named.
@Provides @Named("foo") String provideFoo()
{
return "foo string";
}
Luego puede inyectar la instancia nombrada en su constructor o usar la inyección de campo en su clase dependiente.
public class Thermosiphon
{
@Inject @Named("foo") String fooString;
@Inject public Thermosiphon(Heater heater)
{
System.out.println("value of fooString is " + fooString);
}
}
EDITAR 2018-02-08: Proyecto de muestra que muestra cómo hacer esto en https://github.com/ravn/dagger2-named-string-inject-example - Nota: ¡ toda la fuente está en un solo archivo !
Estoy viendo si Dagger puede reemplazar a Guice para nosotros (ya que nuestra plataforma Java de implementación es lenta).
Construyo un mapa de cadenas de configuración en tiempo de ejecución, que me gustaría que se inyectara con daga cuando fuera necesario.
Eg si tengo
java.util.Map<String, String> map = new java.util.TreeMap<String, String>();
map.put("key", "value");
y
@Inject
Thermosiphon(Heater heater, @Named("key") String value) {
this.heater = heater;
System.out.println("value =" + value);
}
Me gustaría tener "valor" inyectado en valor.
Los ejemplos en el código fuente no tienen ningún uso de @Named. Solo intentarlo da la siguiente excepción:
Exception in thread "main" java.lang.IllegalStateException: Errors creating object graph:
No binding for @javax.inject.Named(value=key)/java.lang.String required by class bar.Thermosiphon
at dagger.internal.ThrowingErrorHandler.handleErrors(ThrowingErrorHandler.java:34)
at dagger.internal.Linker.linkRequested(Linker.java:146)
at dagger.ObjectGraph$DaggerObjectGraph.getInjectableTypeBinding(ObjectGraph.java:288)
at dagger.ObjectGraph$DaggerObjectGraph.get(ObjectGraph.java:249)
at app.CoffeeApp.main(CoffeeApp.java:20)
¿Cómo debo abordar esto?
Parece que tienes un mapa y quieres usar algo que los enlaza automáticamente con cadenas nombradas. No puede hacerlo tan automáticamente en Dagger como en Guice, ya que en Guice puede crear un archivador de propiedades.
Dagger requiere el conocimiento de todos sus enlaces en tiempo de compilación, a fin de hacer el análisis para asegurar que se cumplan todos los enlaces y dependencias.
Dicho esto, se podría hacer algo como esto: es más placa de caldera, pero es legítimo.
@Module(library = true)
public class PropertiesModule {
public final Properties props;
PropertiesModule(Properties props) {
this.props = props;
}
@Provides @Named("property.one") String providePropertyOne() {
props.getProperty("property.one", "some default");
}
@Provides @Named("property.two") String providePropertyTwo() {
props.getProperty("property.two", "some other default");
}
...
}
Esto permitirá que se creen todos los enlaces hte que necesita, pero que se satisfagan con los valores de tiempo de ejecución. Sin embargo, las claves se conocen en tiempo de compilación (y deben serlo, ya que está usando @Named ("literal de cadena") en su código de todos modos. Heck, si ha definido los nombres y valores predeterminados de sus propiedades como cadenas constantes, incluso puede hacer:
@Provides @Named(PROPERTY_NAME_CONSTANT) String a() {
props.getProperty(PROPERTY_NAME_CONSTANT, PROPERTY_NAME_CONSTANT_DEFAULT);
}
Es más placa de caldera, pero Dagger ha intentado, al mismo tiempo que elimina mucha placa de caldera, el análisis de compilación preferido en lugar de la reducción absoluta de placa de caldera. Dicho esto, propondré una característica que mejorará esta situación, generando automáticamente un módulo para las propiedades del sistema a partir de una lista conocida, o algo similar. Creo que incluso esta placa de caldera se puede reducir.