Я учусь использовать Roboguice, и мне сложно понять, как внедрить системный сервис. Все примеры, которые я видел, вводят в действие, но я хочу ввести его в POJO. Я использую Roboguice 2.0 beta 3
У меня есть класс PhoneNumber и я хотел бы добавить службу TelephonyManager.
public class PhoneNumber {
@Inject TelephonyManager mTelephonyManager;
protected Integer getNetworkCountryPrefix() {
// This gives a null pointer exception
mTelephonyManager.getNetworkCountryIso();
}
}
При введении в класс, который расширяет RoboActivity, все работает нормально. Но возможно ли внедрить TelephonyManager в класс, который не расширяет RoboActivity?
Да, есть три основных способа получить инъекцию в ваших объектах при использовании RoboGuice.
Вызовите RoboGuice.injectMembers() самостоятельно для объекта, для которого вы хотите выполнить инъекцию. Для большинства POJO это, вероятно, будет сделано в конструкторе объектов, но также может быть выполнено в другое время. Обратите внимание, что это идеальное решение, но, пожалуй, наименее желательно для параметров, поскольку оно жестко кодирует зависимость от вашей инфраструктуры DI (RoboGuice).
Внедрить в класс, который уже делает # 1 для вас. Вы уже знакомы с этим методом... это именно то, что делает RoboActivity. В основном, большая часть того, что делает RoboActivity, просто вызывает RoboGuice.injectMembers для вас.
Внедрить TelephonyManager в класс, который сам был введен. Обычно это наиболее желательно, хотя в вашем конкретном случае это может быть нежелательно. Позвольте мне объяснить это ниже:
class MyActivity extends RoboActivity {
@Inject PhoneNumber phone;
...
}
class PhoneNumber {
@Inject TelephonyManager tm;
}
В принципе, RoboGuice просто нуждается в возможности выполнить инъекцию на вашем экземпляре. Для обычных POJO, которые не созданы RoboGuice, у RoboGuice нет возможности работать над своей магией, если вы не вызовете непосредственно injectMembers, следовательно, решение №1. Однако, если вы разрешите RoboGuice создавать экземпляр объекта для вас, например. путем инъекции, то RoboGuice имеет контроль над созданием объекта и может делать инъекцию для вас в этом объекте. Таким образом, в приведенном выше примере, когда RoboGuice создает новый PhoneNumber и помещает его в phone
переменную, RoboGuice выполнит инъекцию на экземпляр, и tm
будет введено правильно. Очевидно, что если вы создадите PhoneNumber с помощью оператора new() вместо того, чтобы позволить RoboGuice сделать это, RoboGuice не будет иметь возможности выполнить инъекцию, а tm будет нулевым.
Если № 3 работает для вас, я бы пошел на это. Это самый гибкий способ сделать что-то, и он поощряет хорошие практики, позволяя инфраструктуре DI создавать объекты для вас.
Однако, если PhoneNumber не является тем, что вы обычно позволяете RoboGuice создавать для вас, тогда вам может потребоваться рассмотреть вариант с номером 1.
Вы можете использовать в конструкторе this
RoboGuice.getInjector(context).injectMembers(this);
просто нужен контекст
TelephonyManager не является одним из стандартных стандартных системных сервисов, доступных для инъекций. Вам нужно будет зарегистрировать эту службу в своем модуле, прежде чем вы сможете ввести ее в другие области.
http://code.google.com/p/roboguice/wiki/ProvidedInjections
Сделав это в своем модуле, вы можете зарегистрировать его для инъекций:
bind(TelephonyManager.class).toProvider(new SystemServiceProvider<TelephonyManager>(Context.TELEPHONY_SERVICE));