2016-08-29 5 views
4

У меня есть вопрос относительно Android Dagger 2 и использования аннотаций @Inject и @Provide. Учитывая следующие два упрощенных примера:Android Dagger 2: Inject versus Предоставляет

public class A { 
    String msg; 

    public A(String msg){ 
    this.msg = msg; 
    } 
} 

public class B { 
    public A a; 

    public B(A a){ 
    this.a = a; 
    } 
} 

@Module 
public class AModule { 
    @Provides 
    A providesA(){ 
    return new A("blah"); 
    } 

    @Provides 
    B ProvidesB(A a) 
    { 
    return new B(a); 
    } 
} 

пример довольно прямо вперед, у меня есть два метода в моем AModule с @Provides аннотациями. Поэтому Кинжал может создать объект B, используя экземпляр A со строкой «blah».

Мой второй пример выглядит следующим образом:

public class A { 
    String msg; 

    public A(String msg){ 
    this.msg = msg; 
    } 
} 

public class B { 
    public A a; 

    @Inject 
    public B(A a){ 
    this.a = a; 
    } 
} 

@Module 
public class AModule { 
    @Provides 
    A providesA(){ 
    return new A("blah"); 
    } 
} 

В этом примере Dagger может создать экземпляр B, потому что объект А может быть создан с помощью AModule. Экземпляр B может быть создан, потому что его конструктор использует аннотацию @Inject.

Так что мой вопрос: в чем разница между этими двумя примерами. Оба, похоже, имеют одинаковую семантику. Сгенерированный код отличается и есть ли какие-либо подводные камни? Или это просто вопрос или личный вкус или лучшие практики?

ответ

7

Они работают аналогично, а стиль @Inject предпочтительнее, когда у вас есть такой простой выбор, как в вашем примере. Тем не менее, это не всегда так:

  • Если B, потребляющий A, не находится под вашим контролем, а не DI-aware, вы не сможете добавить аннотацию @Inject.
  • Если B - это интерфейс, вам понадобится @Provides (или @Binds в новых версиях кинжала), чтобы определить, какую реализацию использовать.
  • Если вы не используете графический объект Dagger для каждого введенного параметра, вы можете вызвать конструктор вручную, будет ли он помечен как @Inject или нет. Это может быть так, если вы хотите, чтобы конкретный экземпляр или константа был параметром конструктора, но вы не можете или не хотите настраивать привязку для всего графа объектов.
  • Если вы хотите, чтобы ваша привязка возвращалась null, иногда или иным образом выбирайте между реализациями, эта логика может жить в методе @Provides.
Смежные вопросы