Ich gehe davon aus, dass Sie weder Module noch Komponenten erwähnen, mit denen Sie nicht vertraut sind und wie sie zusammenarbeiten.
Ihr Beispiel funktioniert nicht, da Dagger 2 nicht weiß, dass zur Erstellung eines Produkts eine der Klassen ProductOne oder ProductTwo verwendet werden muss. Auch wenn Dolch 2 sie verarbeiten wird (weil sie beide mit @Inject markiert wurden), wird es nicht automatisch davon ausgehen, dass sie nur dort eingesetzt werden, wo sie das Produkt implementieren. Der Grund dafür ist, dass es nicht wissen würde, welches zu verwenden ist, wenn es mehr als eins gibt, wie in diesem Fall.
Sie müssen also eine Bindung von ProductOne oder ProductTwo mit der Schnittstelle Produkt erstellen. Sie tun dies durch ein Modul.
@Module
public class ProductOneModule {
@Provides Product provideProduct(ProductOne productOne) {
return productOne;
}
}
Ein Modul bietet nur eine Reihe von wiederverwendbaren Bindungen. Sie werden nicht wirklich verwendet (oder validiert), wenn sie nicht von einer Komponente verwendet werden. Eine Komponente kapselt all diese Informationen und verwaltet deren Erstellung. Dabei werden Module und ihre Bindungen und Factories verwendet, die für Klassen mit @Inject-Konstruktoren erstellt wurden.
Wenn Sie eine Komponente wie diese erstellen, wird Dolch 2 fehlschlagen, da es, wie oben erwähnt, nicht weiß, wie ein Produkt hergestellt wird.
@Component
public interface PackagerOneComponent {
Packager packager();
}
Der Fehler in etwa so sein wird:
Product cannot be provided without an @Provides-annotated method.
Packager.(Product product)
[parameter: Product product]
Das bedeutet, dass, wenn ein Packager
Objekt zu erstellen versuchen, es nicht eine geeignete Bindung für seine Product
Parameter finden konnte. Der Weg, dies zu beheben, besteht darin, das Modul mit seiner Bindung von Product < ProductOne
anzugeben.
@Component(modules = ProductOneModule.class)
public interface PackagerOneComponent {
Packager packager();
}
Jetzt weiß er, dass ein Product
zu schaffen es ProductOneModule.provideProduct(ProductOne)
und um aufrufen muss anrufen, dass es eine ProductOne
erstellen muss, die es weiß, wie zu tun, weil Sie einen seiner Konstruktor mit @Inject
markiert haben.
Natürlich, wenn Sie ProductTwo verwenden möchten, dann können Sie einfach ein anderes Modul und eine andere Komponente erstellen.
@Module
public class ProductTwoModule {
@Provides Product provideProduct(ProductTwo productTwo) {
return productTwo;
}
}
@Component(modules = ProductTwoModule.class)
public interface PackagerTwoComponent {
Packager packager();
}
Das Problem bei einem Qualifikationsspiel in diesem Fall, entweder ein benutzerdefinierter einer oder Benannt ist, dass mit Qualifier Sie fest Paar der Injektionsstelle mit einer spezifischen Implementierung. Dies ist in einigen Fällen definitiv erforderlich, z. Wenn Sie zwei lange Instanzen haben, von denen eine eine Zeitüberschreitung und eine eine Zeitüberschreitung darstellt, möchten Sie nicht, dass sie verwechselt werden. Daher müssen Sie unbedingt Qualifikationsmerkmale verwenden, um sie zu unterscheiden.
In diesem Fall ist es jedoch wahrscheinlich, dass einige Benutzer oder die Verpackung ProductOne verwenden möchten und einige ProductTwo verwenden möchten. Andernfalls sollte Packager einfach ProductOne oder ProductTwo direkt nehmen und die Schnittstelle vermeiden.
Dieser Ansatz ermöglicht zwei verschiedene Teile Ihres Codes Packager mit zwei verschiedenen Implementierungen von Product
, z. Ihre Produktion und Ihre Tests.
Natürlich können Sie zwei verschiedene Implementierungen verwenden, auch wenn sie mit einem Qualifier versehen sind, aber Sie müssen immer noch eine Vielzahl dieser Technik verwenden.
Überprüfen Sie @Inject Annotation Implementierung von Java und Ihre Verwirrung wird abgesehen von Gewinn Hölle des Wissens gelöscht werden !!! – hagrawal
Ich glaube nicht, dass das funktioniert. Hast du es versucht? Gibt es einen Code, der '' ein 'Produkt' liefert? Weil das '@ Inject' dem Dolch nur sagt, wo andere Dinge injiziert werden sollen. Aber es sagt Dolch nicht, es an anderen Orten zu verwenden. – zapl
@zapl für den ersten Fall nur mit einer konkreten Klasse habe ich es versucht und es hat funktioniert. Aber für zwei konkrete Klasse habe ich es nicht ausprobiert. – vsvankhede