Ich studiere Gurke bei The Cucumber for Java Book, aber es gibt ein Argument dafür, dass dem Objekt PicoContainer injiziert werden soll. Ich habe nicht geschrieben, wie man es mit dem Konstruktor von generiert, also habe ich es nachgeschlagen. (Tatsächlich funktionierte das neueste Active JDBC (1.4.13) nicht mit dem Beispielbuch (es funktionierte mit derselben Version von 1.4.1 wie das Buch), daher brauchte ich eine Alternative.)
Dies ist eine teilweise Modifikation des Beispiels im obigen Buch, aber ich möchte das Account-Objekt mit cumcumber-picocontainer in der Schrittdefinition DI, aber ich muss das Argument im Konstruktor angeben, wenn ich das Account-Objekt erstelle.
Account.java
public class Account extends Model {
public Account() {
}
public Account(int number) {
setInteger("number", number);
setString("balance", "0.00");
saveIt();
}
...
AccountSteps.java
public class AccountSteps {
private Account account;
public AccountSteps(Account account) {
this.account = account;
}
...
In diesem Buch wird dasselbe erreicht, indem eine untergeordnete Klasse erstellt und wie unten gezeigt DI erstellt wird, anstatt den Konstruktor mit Argumenten direkt zu verwenden.
TestAccount.java
public class TestAccount extends Account {
public TestAccount() {
super(1234);
}
...
AccountSteps.java
public class AccountSteps {
private TestAccount account;
public AccountSteps(TestAccount account) {
this.account = account;
}
...
Wie kann ich das vom Konstruktor erstellte Account-Objekt direkt mit Argumenten DI, ohne dies zu tun?
Wenn Sie PicoContainer direkt anstelle von Cucumber verwenden, können Sie entweder das Objekt erstellen, das Sie DI erstellen möchten, oder Sie können festlegen, dass das Objekt mithilfe eines Konstruktors mit Argumenten erstellt wird.
MutablePicoContainer pico = new DefaultPicoContainer();
pico.addComponent(new Account(5)); //Erstellen Sie ein Kontoobjekt mit einem Konstruktor mit Argumenten
//Oder geben Sie das Argument des Konstruktors an
pico.addComponent(Account.class, Account.class, new Parameter[] { new ConstantParameter(new Integer(5)) });
Account account = pico.getComponent(Account.class);
System.out.println("number = " + account.getNumber());
Bei der Ausführung von Cucumber wird MutablePicoContainer von Cumcumber generiert und setzt die Komponenten auch auf DI, sodass die normale Benutzerseite leicht nichts tun kann, im Gegenteil, ich möchte es selbst festlegen In diesem Fall gibt es keine Möglichkeit, den MutablePicoContainer von Cucumber abzurufen, sodass nichts unternommen werden kann.
Es gab natürlich eine ähnliche Anfrage (Möglichkeit zum Konfigurieren von PicoContainer), und die ObjectFactory-API war als Antwort verfügbar. Mit dieser API können Sie jedoch Folgendes tun
pico.addComponent(Account.class)
(Dies ist zwar sinnvoll, da Sie damit angeben können, welche Implementierungsklasse für die Schnittstelle verwendet werden soll.)
pico.addComponent(new Account(5));
pico.addComponent(Account.class, Account.class, new Parameter[] { new ConstantParameter(new Integer(5)) });
Es scheint derzeit nicht möglich zu sein, eine Instanz zu registrieren oder ein Argument eines solchen Konstruktors anzugeben.
Wenn das Argument eine reguläre Klasse anstelle von int wie in diesem Beispiel ist, können Sie dies normal tun. Als DI-Anfänger habe ich eine Weile gebraucht, um das zu bemerken. Da Gurken-Picocontainer clever ist, wird das Argumentobjekt des Konstruktors automatisch DI, ohne etwas zu sagen. Es ist also eine etwas schmutzige Implementierung, aber wenn Sie eine Klasse (AccountNumber) für das Argument des Konstruktors erstellen, können Sie tun, was Sie wollen.
Account.java
public class Account extends Model {
public Account() {
}
public Account(int number) {
setInteger("number", number);
setString("balance", "0.00");
saveIt();
}
//Konstruktor für DI
public Account(AccountNumber number) {
this(number.getNumber());
}
...
AccountNumber.java
public class AccountNumber {
private int number;
public AccountNumber() {
number = 1234;
}
public int getNumber() {
return number;
}
}
Sie können jetzt das mit den Argumenten erstellte Kontoobjekt übergeben, ohne die Schrittdefinition zu ändern.
AccountSteps.java
public class AccountSteps {
private Account account;
public AccountSteps(Account account) {
this.account = account;
}
...
Recommended Posts