Google Guice (Assisted Injects) - Buggy oder mach ich's falsch?

Mujahiddin

Top Contributor
Hallo, ich versuche mich gerade an einem kleinen Programm und verwende dafür Google Guice.
Beim Programm soll der Benutzer seinen Namen und Passwort eingeben und da diese erst zur Laufzeit bekannt sind, verwende ich für diese Implementierung AssistedInject.
Ich habe hierfür ein Interface UserFactory mit der Methode
Code:
User create(@Assisted("Username") String username, @Assisted("Password") String password);
Am Anfang des Programms wird dieser User einmalig initialisiert mittels:
Java:
User user = getInjector().getInstance( UserFactory.class ).create( username, password );
und in den folgenden Programmabschnitten will ich auf diese Instanz zugreifen. Dafür habe ich den Scope bereits auf Singleton gesetzt.
Das Problem ist aber, dass ich dauernd Fehlermeldungen kriege. Guice meckert, dass ich keine Variablen übergeben habe. Und wenn ich in die configure-Methode
Code:
bind( User.class ).in( Singleton.class );
mache, kommt ein Fehler, dass es keine Deklaration für die Annotation "Assisted" gibt (Es ist ja immerhin so, dass man vor Parametern eine Annotation setzen kann, um diese eindeutig zu identifizieren. Diesen müssen im Injector eine Dependency gegeben werden.)

Ich werde evtl ein KSKB posten. Weiß jemand aber, wie man das umgehen kann?

Edit: Ich verwende Guice 3.0,

hier mal das KSKB:

Java:
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.FactoryModuleBuilder;


public class KSKB {
	
	@Singleton
	public static class User {
		
		public final String	name;
		
		@Inject
		public User(@Assisted("Username") String username) {
			this.name = username;
		}
		
		public static interface Factory {
			
			public User create(@Assisted("Username") String username);
		}
	}
	
	public static void main(String... args) {
		Injector injector = Guice.createInjector( new AbstractModule() {
			
			@Override
			protected void configure() {
				install( new FactoryModuleBuilder().build( User.Factory.class ) );
//				bind( User.class );
			}
			
		} );
		User user = injector.getInstance( User.Factory.class ).create( "Guice" );
		System.out.println( user.name );
		
//		user = injector.getInstance( User.class ); // doesn't work - throws Exception!!
//		System.out.println( user.name );
	}
}

Die auskommentierten Stellen erzeugen den Fehler. Vor allem die letzten 2 Zeilen Code leuchten mir einfach nicht ein!
 
Zuletzt bearbeitet:
Ich glaube mal irgendwo gelesen zu haben, dass Guice keine inneren Klassen unterstützt (keine Ahnung, ob das noch aktuell ist). Außerdem: Wenn bei dir alle Konstruktorparameter "assisted" sind, wozu bauchst du dann überhaupt eine Injection?
 
1. sind das verschachtelte Klassen und 2. ist das nur ein KSKB und deshalb sind sie verschachtelt. Bei meinem Programm sind das eigene Dateien und somit eigene Klassen.

Was soll ich denn sonst tun, wenn nicht Injection? Ganz auf Guice verzichten?
 
Wozu AssistedInjection? Ich sehe keine Notwendigkeit für ein Singelton ein FactoryPattern zu verwenden. Wieso muss der Name schon beim erstellen des Objektes bekannt sein? Würde ein Feld mit Getter/Setter nicht reichen, dass du dann an entsprechender Stelle setzt.
 
Ich habe das Problem auf eine andere Weise gelöst, und zwar mit einer Klasse
Code:
UserManager
.
Diese Vorgehensweise ist sehr praktisch für mein Vorhaben, ich habe nämlich mehrere Benutzer, die in einer Liste gespeichert sind und die an einen Thread zugewiesen werden, welcher sich um die Kommunikation kümmert.
Der
Code:
UserManager
ist ein Singleton und hat Methoden zum Erstellen eines Benutzers (also einmalig vor dem Übergeben an den Thread) und Methoden, um einen Benutzer anhand des Namens / des Sockets zu identifizieren.

Allerdings gibt es während der ganzen Laufzeit meines Servers (welcher Useranfragen empfängt) eine Verbindung zur Datenbank und die muss mit einer Eingabe aus DB-Username und Passwort initiiert werden. Hier bin ich so vorgegangen, dass das
Code:
ConnectionModule
beim Konstruieren diese zwei Werte erwartet. Sobald in der Klasse
Code:
DatabaseConnectionService implements ConnectionService
die Verbindung hergestellt wird, wird das Passwort aus dem char-Array gelöscht. DatabaseConnectionService ist hierbei ein Singleton.

Die Hilfe kam aus einem Thread der Seite StackOverflow - Hier der Link zur Frage:
java - Output of "Assisted" factory should be @Singleton - Stack Overflow
 

Zurück
Oben