2017-02-07 10 views
1

Я пытаюсь сохранить свой пользовательский объект как синглтон с Dagger 2.Dagger 2 REINIT одноточечно

@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(); 
     } 
    } 

Он отлично работает и впрыскивает свои классы с объектом User.

Однако после входа в систему и извлечения пользователя с сервера и сохранения его в том месте, в котором этот метод запрашивает вышеуказанный метод, он не вступает в силу, поскольку он является одиночным. Он предоставит мне нулевой пользовательский объект. Для его вступления в силу вы должны отказаться от приложения и повторно открыть его ...

Вопрос заключается в том, как обновить/повторно инициализировать объект пользователя, аннотированный с помощью @Name («me») после изменения фактических данных, чтобы он вводит мои другие классы в текущий пользовательский объект?

+0

Вам необходимо перезагрузить модуль и снова инициализировать его. –

ответ

1

Тогда он больше не может быть аннотирован Singleton. Вы должны создать свой собственный Scope.

Затем вы берете на себя ответственность за объект, аннотированный с помощью вашей собственной области. Как только ваш User будет обновлен, вы избавитесь от предыдущего компонента, который предоставил объект User, т. Е. Его обнуление. Затем вы создаете новый компонент, и в следующий раз, когда вы попросите компонент получить вас User, он создаст новый.

Знайте, что любой другой метод провайдера в модуле, который был аннотирован вашей настраиваемой областью, также возвращает вновь созданный объект.

Here's сообщение в блоге, описывающее, как это сделать.

+1

Этот ответ неверен - пользовательские области функционально идентичны «@ Singleton». Прочтите это: http://www.techyourchance.com/dagger-2-scopes-demystified/. – Vasiliy

+0

@ Vasiliy, не могли бы вы пояснить, что именно неверно? Потому что я могу уточнить, почему ответ правильный. Компонент может иметь только одну область, он не может иметь несколько областей. '@ Singleton' - это просто область, поставляемая с кинжалом, ее можно назвать чем угодно, она не имеет каких-либо конкретных функций, связанных с ней.Таким образом, если вы создаете компонент с определенной областью, то объект, который этот компонент предоставляет, всегда будет одинаковым (то есть singleton). Что вам нужно сделать - это избавиться от компонента и создать новый, тогда будет предоставлен новый объект, который является ответом. – azizbekian

+0

То, что вы говорите в этом комментарии, близко к правильному, но это не то, что указано в начале вашего ответа: «Тогда это больше не может быть аннотировано с помощью Singleton. Вам нужно создать свой собственный масштаб». Почему я говорю «близко к правильному»? Повторная копия компонента будет «перезагружать» ВСЕ аннотированные объекты, предоставляемые этим компонентом. Предоставление этого совета без упоминания такого разрушительного побочного эффекта является неполным IMHO – Vasiliy

0

Я не собираюсь отвечать на ваш прямой вопрос, но даю вам совет, как правильно реализовать необходимые функции.

Вы в основном пытаетесь реализовать какую-то функцию UserManager. Но вместо того, чтобы инкапсулировать эту логику в выделенный класс, вы пытаетесь делегировать ответственность управления пользователями за рамки DI.

Это злоупотребление каркасом DI и очень неряшливый путь.

Что вам нужно, это просто так:

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

И выставить требуемое funcitonality в 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(); 
     } 
    } 
} 

Вы можете увидеть this и this ответы, чтобы получить некоторый дополнительный контекст о рамках Д.И. злоупотребление.

Вы также можете прочитать это сообщение: Dependency Injection in Android.

Смежные вопросы