2016-03-18 19 views
12

Ich war etwas faul und verwendete fast ausschließlich Feldspritzen. Ich stellte nur einen leeren Konstruktor zur Verfügung, legte meine @Inject-Felder ein. Alles sah einfach und gut aus. Die Feldinjektion hat jedoch ihre Kompromisse, daher habe ich einige einfache Regeln entwickelt, die mir helfen zu entscheiden, wann ein Feld verwendet werden soll und wann Konstruktorinjektionen zu verwenden sind. Ich freue mich über jede Rückmeldung, wenn ein Fehler in meiner Logik vorliegt oder wenn Sie zusätzliche Überlegungen hinzufügen müssen.Dolch 2: Wann werden Konstruktorinjektionen und wann Feldinjektionen verwendet?

Zuerst eine Klarstellung, um auf der gleichen Seite zu sein:

Constructor Injektion:

@Inject 
public SomeClass(@Named("app version") String appVersion, 
        AppPrefs appPrefs) {... 

Gleiche mit dem Feld Injektion:

public class SomeClass { 
    @Inject 
    @Named("app version") String mAppVersion; 

    @Inject 
    AppPrefs appPrefs; 

Regel 1: MUST Feld verwenden Injektion, wenn ich nicht die Erstellung des Objekts Kontrolle (denke Aktivität oder Fragment in Android). Wenn ein (nicht dolchbewußtes) Framework mein Objekt erstellt und es für mich handhabt, habe ich keine andere Wahl, als es manuell zu injizieren, nachdem ich die Instanz erhalten habe.

Regel 2: MUSS die Konstruktorinjektion verwenden, wenn die Klasse in einem anderen Projekt verwendet wird/wird, das Dolch 2 nicht verwendet. Wenn die anderen Projekte Dolch nicht verwenden, können sie DI nicht verwenden, so dass der Benutzer das Objekt mit new auf die "alte" Weise erstellen muss.

Regel 3: PREFER-Konstruktorinjektion bei der Arbeit mit Klassenhierarchien, da es einfacher ist, Komponententests zu erstellen.

Klarstellung:

Berücksichtigung der folgenden Struktur, die Feld Injektion verwendet:

package superclass; 

public class SuperClass { 
    @Inject 
    HttpClient mHttpClient; 
    ... 
} 

.

package differentpackage; 

public class SubClass extends SuperClass { 
    public SubClass() { 
    } 
} 

Wenn ich Unit-Test für SubClass im Verzeichnis test/java/differentpackage erschaffe habe ich keine andere Wahl, als die gesamte DI-Infrastruktur zu bringen, um bis zu der Lage sein, die HttpClient zu injizieren. wenn ich wurde mit Konstruktor Injektion wie dies im Gegensatz dazu:

public class SuperClass { 
    private final HttpClient mHttpClient; 

    @Inject 
    public SuperClass(HttpClient httpClient) { 
     mHttpClient = httpClient; 
    } 
} 

in meinem Unit-Test konnte ich einfach:

HttpClient mockHttp = mock(HttpClient.class); 

Subclass tested = new Subclass(mockHttp); 

// tests 

Also im Grunde jetzt ich in der anderen Extrem bin: Ich neige dazu, meist vertrauen Konstruktorinjektionen und Feldinjektionen nur verwenden, wenn "Regel 1" zutrifft. Das einzige ‚Problem‘, das ich mit dem Konstruktor injiziert ist, dass für ‚Ende‘ Klassen manchmal Konstrukteuren ganz mit den Parametern überlastet werden und sie sehen die ausführliche und hässlich wie folgt aus:

@Inject 
public ModelMainImpl(@Named("app version") String appVersion, 
        AppPrefs appPrefs, 
        LoginPrefs loginPrefs, 
        @ForApplication Context appContext, 
        NetworkInfoProvider networkInfoProvider, 
        AndroidEventPoster androidEventPoster, 
        Session session, 
        ForgeExchangeManager exchangeManager, 
        HttpFunctionality httpFunctionality, 
        @Named("base url") String baseUrl, 
        @Named("forge result producer") ResultProducer<ForgeExchangeResult> resultProducer 
        ) { 

Jungs, was sind Ihre Regeln Wählen Sie zwischen Konstruktor und Feld injiziert? Ich vermisse etwas, gibt es Fehler in meiner Logik?

+0

https://stackoverflow.com/questions/39207845/android-dagger-2-inject-versus-provides Schauen Sie sich das auch an, bietet einen guten Einblick –

Antwort

5

Konstruktorinjektion verwenden. Wenn Sie das nicht können, verwenden Sie die Eigenschaft injection.

Regel 1 scheint in Ordnung, wie Dekorationen oder Attribute können Sie Property (Feld) Injektion verwenden.

Regel 2 scheint in Ordnung zu sein, denn wer Ihre Klasse benutzt, muss Ihrem Konstruktor folgen. Sie wissen vielleicht nicht, dass sie auch Ihre Immobilie intialisieren müssen.

Regel 3 Es ist nicht nur gut für Unit-Test. Es ist gut für die Anwendung der Einzelverantwortung. Es ist einfacher, Ihr Objektdiagramm zu sehen. Andernfalls verbergen Sie es mit der Eigenschaft.

Wenn wir in Ihrer Frage kommen, ja, es gibt viele Parameter in Ihrem Konstruktor. Aber die Lösung ist keine Eigenschaft Injektion. Sie können Ihren Code umgestalten und aggregate services

verwenden
Verwandte Themen