2017-02-07 6 views
1

Ich versuche, mein Benutzerobjekt als Singleton zu speichern mit Dolch 2.Dagger 2 reinit Singletons

@Provides 
    @Named("me") 
    @Singleton 
    User provideUser(PrefsUtil prefsUtil, UserDao userDao) { 
     int id = prefsUtil.getFromPrefs("me", 0); 
     if (id == 0){ 
      return new User(); 
     } 
     try { 
      return userDao.queryForId(id); 
     } catch (SQLException e) { 
      return new User(); 
     } 
    } 

Es funktioniert gut und spritzt meine Klassen mit Benutzerobjekt.

Nach dem Anmelden und Abrufen des Benutzers vom Server und Speichern an der Stelle, an der die obige Methode sie abruft, wird sie jedoch nicht wirksam, da es sich um ein Singleton handelt. Es wird mir das Null-Benutzerobjekt zur Verfügung stellen. Damit es Effekt Anwendung beenden müssen nehmen und es wieder öffnen ...

Die Frage ist, wie das Benutzerobjekt mit @Name („me“) nach den eigentlichen Daten kommentierte aktualisieren/neu initialisiert wird, so dass es geändert spritzt meine anderen Klassen mit dem aktuellen Benutzerobjekt?

+0

Sie müssen das Modul zurücksetzen und erneut initialisieren. –

Antwort

1

Dann darf es nicht mehr mit Singleton kommentiert werden. Sie müssen Ihre benutzerdefinierte Scope erstellen.

Dann übernehmen Sie die Verantwortung für das mit Ihrem benutzerdefinierten Bereich annotierte Objekt. Sobald Ihr User aktualisiert wurde, werden Sie die vorherige Komponente los, die User Objekt zur Verfügung gestellt hat, d. H. Es auf Null setzen. Dann erstellen Sie eine neue Komponente und das nächste Mal, wenn Sie die Komponente bitten, Sie zu holen, wird die User eine neue Komponente erstellen.

Beachten Sie, dass jede andere Anbietermethode im Modul, die mit Ihrem benutzerdefinierten Bereich versehen wurde, auch ein neu erstelltes Objekt zurückgibt.

Here's ein Blogbeitrag beschreibt, wie man das macht.

+1

Diese Antwort ist falsch - benutzerdefinierte Bereiche sind funktional identisch mit '@ Singleton'. Lesen Sie hierzu: http://www.techyourchance.com/dagger-2-scopes-demystified/. – Vasiliy

+0

@Vasiliy, würdest du bitte klarstellen, was genau falsch ist? Weil ich erklären kann, warum die Antwort richtig ist. Eine Komponente darf nur einen Bereich haben, sie darf nicht mehrere Bereiche haben. '@ Singleton' ist nur ein Oszilloskop, das mit Dolch ausgeliefert wird. Es kann irgendwas heißen, es besitzt keine spezifische Funktionalität.Wenn Sie also eine Komponente mit einem bestimmten Bereich erstellen, ist das Objekt, das diese Komponente bereitstellt, immer dasselbe (d. H. Singleton). Was Sie tun müssen - ist, die Komponente loszuwerden und eine neue zu erstellen, dann wird ein neues Objekt bereitgestellt, welches die Antwort ist. – azizbekian

+0

Was Sie in diesem Kommentar sagen, ist in der Nähe richtig, aber es ist nicht das, was am Anfang Ihrer Antwort steht: "Dann kann es nicht mehr mit Singleton kommentiert werden. Sie müssen Ihr benutzerdefiniertes Scope erstellen". Warum sage ich "nah, um richtig zu sein"? Die erneute Instanziierung der Komponente wird alle von dieser Komponente bereitgestellten annotierten Objekte "zurücksetzen". Diesen Rat zu geben, ohne solch einen verheerenden Nebeneffekt zu erwähnen, ist irgendwie unvollständig. IMHO – Vasiliy

0

Ich werde nicht Ihre direkte Frage beantworten, aber geben Sie einen Ratschlag, wie Sie die Funktionalität, die Sie benötigen, richtig implementieren.

Sie versuchen im Grunde, eine Art von UserManager Funktionalität zu implementieren. Aber anstatt diese Logik in eine dedizierte Klasse zu kapseln, versuchen Sie, die Verantwortlichkeiten der Benutzerverwaltung an das DI-Framework zu delegieren.

Dies ist ein Missbrauch von DI-Framework und sehr schlampig Weg zu gehen.

Was Sie brauchen, ist nur dies:

@Provides 
@Singleton 
UserManager provideUserManager(PrefsUtil prefsUtil, UserDao userDao) { 
    return new UserManager(prefUtils, userDao); 
} 

und setzen die erforderlichen funcitonality in UserManager:

public class UserManager { 

    private final PrefsUtil mPrefsUtil; 
    private final UserDao mUserDao; 

    public UserManager(PrefsUtil prefsUtil, UserDao userDao) { 
     mPrefsUtil = prefsUtil; 
     mUserDao = userDao; 
    } 

    public User getCurrentUser() { 
     int id = mPrefsUtil.getFromPrefs("me", 0); 
     if (id == 0){ 
      return new User(); 
     } 
     try { 
      return mUserDao.queryForId(id); 
     } catch (SQLException e) { 
      return new User(); 
     } 
    } 
} 

Sie können this und this Antworten, um sehen einige zusätzliche Kontext über DI Rahmen zu erhalten Missbrauch.

Vielleicht möchten Sie auch diesen Beitrag lesen: Dependency Injection in Android.