2016-03-28 4 views
3

Я создал gist, выделив проблему, с которой я сталкиваюсь. Я использую модуль приложения, чтобы обеспечить зависимость от меня Firebase для ввода в другое место.Нулевая ссылка на кинжал 2 @Inject

Когда я пытаюсь использовать @Inject Firebase mFirebase в слое данных, эта зависимость никогда не выполняется.

Я пытаюсь сохранить Context из других моих слоев, но сервис Firebase зависит от этого. Я заинтересован в изучении любых других шаблонов, которые помогут сохранить классы Android из моей бизнес-логики.

FirebaseService.java

public class FirebaseService { 

@Inject Firebase mFirebaseRef; //NEVER GET'S INJECTED! 

    @Override 
    public LoginResult signinWithEmail(final String email, final String password) { 
     mFirebaseRef.dostuff(); //THIS REFERENCE DOESN'T GET INJECTED! 
    } 
} 

ApplicationModule

@Provides 
@Singleton 
Firebase provideFirebase(@ApplicationContext Context context) { 
    Firebase.setAndroidContext(context); 
    return new Firebase(Util.FIREBASE_URL); 
} 

ApplicationComponent

@Singleton 
@Component(modules = ApplicationModule.class) 
public interface ApplicationComponent { 

    @ApplicationContext Context context(); 
    Application application(); 
    Firebase firebase(); 
} 

MyActivity

public class MyActivity extends AppCompatActivity { 

private ActivityComponent mActivityComponent; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
} 

public ActivityComponent getActivityComponent() { 
    if (mActivityComponent == null) { 
     mActivityComponent = DaggerActivityComponent.builder() 
       .activityModule(new ActivityModule(this)) 
       .applicationComponent(MyApplication.get(this).getComponent()) 
       .build(); 
    } 
    return mActivityComponent; 
} 

Полный пример кода на github

+2

Недостаточно ссылок на код, поскольку ссылки имеют тенденцию к гниению (плюс это требует от нас выхода на другой сайт и чтения). Пожалуйста, добавьте минимальный код в свой вопрос. –

ответ

4

Комментирование поле с @Inject недостаточно для инъекции поле для работы. Там нет волшебства, вам просто нужно сказать Кинжал, чтобы сделать инъекцию.

Во-первых, добавьте этот метод к вашему ApplicationComponent:

void inject(FirebaseService firebaseService); 

Затем этот метод вызывается из вашего FirebaseService (я предполагаю, что это Android-сервис, так что добавьте к этому методу onCreate):

applicationComponent.inject(this); 

Это должно сделать трюк. Есть отличный ответ на аналогичную проблему here.

EDIT

Я посмотрел на вашем хранилище, и я думаю, что вы даже не нужна инъекция поля в этом случае. Вы можете просто указать зависимость Firebase через конструктор. Вот ваш @Provides метод:

@Provides 
@Singleton 
LoginService provideLoginService() { 
    return new FirebaseLoginService(); 
} 

Добавить Firebase в качестве параметра к нему и передать его в FirebaseLoginService конструктор:

@Provides 
@Singleton 
LoginService provideLoginService(Firebase firebase) { 
    return new FirebaseLoginService(firebase); 
} 

Конструктор:

public FirebaseLoginService(Firebase firebase) { 
    this.mFirebaseRef = firebase; 
} 

Удалите @Inject аннотацию с вашего mFirebaseRef поле, поскольку оно больше не нужно.

Вот соответствующие pull request.

+0

Спасибо за ответ, «FirebaseService» не является собственно Android-сервисом, это служба поддержки API. Как получить ссылку на 'applicationComponent' в FirebaseService для выполнения' .inject (this) '? – Reustonium

+1

@Reustonium, я просмотрел ваш репозиторий и отредактировал свой ответ. –

+0

@Reustonium, отвечая на ваш вопрос относительно ссылки 'applicationComponent' - он объявлен в вашем классе' Application', поэтому вам нужно будет предоставить 'Context' в' FirebaseLoginService', а затем получить его из 'Context'. –

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