2011-12-20 2 views
1

Я учусь использовать Roboguice, и у меня возникли проблемы с пониманием того, как вводить системный сервис. Все примеры, которые я видел, вводят в действие, но я хочу ввести его в POJO. Я использую Roboguice 2.0 beta 3Служба инъекции Roboguice

У меня есть класс PhoneNumber и вы хотите ввести службу TelephonyManager.

public class PhoneNumber { 
    @Inject TelephonyManager mTelephonyManager; 

    protected Integer getNetworkCountryPrefix() { 

     // This gives a null pointer exception 
     mTelephonyManager.getNetworkCountryIso(); 
    } 
} 

При введении в класс, который расширяет RoboActivity, все работает нормально. Но возможно ли внедрить TelephonyManager в класс, который не расширяет RoboActivity?

ответ

9

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

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

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

  3. Inject 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

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

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

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

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

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

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

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

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