Система впрыскивания Roboguice

1

Я учусь использовать 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?

Теги:
dependency-injection
guice
roboguice

3 ответа

9
Лучший ответ

Да, есть три основных способа получить инъекцию в ваших объектах при использовании RoboGuice.

  1. Вызовите RoboGuice.injectMembers() самостоятельно для объекта, для которого вы хотите выполнить инъекцию. Для большинства POJO это, вероятно, будет сделано в конструкторе объектов, но также может быть выполнено в другое время. Обратите внимание, что это идеальное решение, но, пожалуй, наименее желательно для параметров, поскольку оно жестко кодирует зависимость от вашей инфраструктуры DI (RoboGuice).

  2. Внедрить в класс, который уже делает # 1 для вас. Вы уже знакомы с этим методом... это именно то, что делает RoboActivity. В основном, большая часть того, что делает RoboActivity, просто вызывает RoboGuice.injectMembers для вас.

  3. Внедрить 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.

  • 0
    Спасибо, что многое прояснилось.
1

Вы можете использовать в конструкторе this

RoboGuice.getInjector(context).injectMembers(this);

просто нужен контекст

1

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

http://code.google.com/p/roboguice/wiki/ProvidedInjections

Сделав это в своем модуле, вы можете зарегистрировать его для инъекций:

bind(TelephonyManager.class).toProvider(new SystemServiceProvider<TelephonyManager>(Context.TELEPHONY_SERVICE));

Ещё вопросы

Сообщество Overcoder
Наверх
Меню