2016-03-10 3 views
1

У меня есть объект домена - предположим, что это Car - который содержит реализацию репозитория, которую я вводил с помощью кинжала. Когда я тестирую свою сущность, я заменяю хранилище для макетной реализации. Car также implements Parcelable.Вкладные зависимости в не-парцелированные объекты - наилучшая практика?

Dagger можно построить объект, когда Car(Engine) вызывается, но это, очевидно, не в состоянии сделать, когда Car(Parcel) вызывается, так как он называется внутренне Parcelization Framework (обычно при получении Car из Intent).

Полезно ли вводить зависимости вручную в конструкторе Car(Parcel)? В качестве альтернативы, есть ли наилучшая практика, которую вы могли бы порекомендовать? Инъекционные зависимости в конструкторе Parcel определенно решат мои проблемы, но рекомендуется, чтобы зависимости не вводились в конструкторы, чтобы поддерживать разделение проблем между инстанцированием и логикой впрыска.

Вот мой домен объект

public class Car implements Parcelable { 

    @Inject ICarRepository CarRepositoryImpl; 

    private Engine engine; // User specified engine passed through constructor 

    public Car(Engine engine) { 
     this.engine = engine; 
    } 

    public Car(Parcel parcel) { 
     this.engine = getEngine(parcel); // Read engine from parcel 
     // Inject dependencies here? 
    } 

    // Static Parcelable creator and other methods follow... 
} 
+0

Я не думаю, что кто-нибудь может ответить на этот вопрос. Я не знаю, почему вам нужен «CarRepositoryImpl» в классе модели (похоже, что это должна быть простая модель?) Или почему вы не используете инъекцию конструктора, но вставляете объект как-то в другое место. Кроме того, если каждое поле также является дополнительным, вы можете просто посылить объект и воссоздать его в целом. (Опять же, я думаю, что parcelable/должен просто использоваться классами моделей, следовательно ... почему эта зависимость?) –

+0

Это не модель. Это объект уровня домена, который представляет собой бизнес-логику в моем приложении. Мне нужен репозиторий, поэтому я выступаю в качестве интерфейса между уровнем персистентности и уровнем домена (бизнес-логики). – aashrey99

ответ

2

комментарий Дэвида на ваш вопрос пятно на - почему бы Car есть зависимость от CarRepository? Это, безусловно, анти-шаблон. Хранилища используются для отграничения объектов от моделирования/персистентности; здесь вы вводите один, по-видимому, никакой причины вообще. Однако предположим на минуту, что вы просто разместили репозиторий там для примера.

Конечно, у кинжала нет автоматического способа создания объекта, если он не имеет разницы. Это означает, что нам придется призывать Кинжал куда-нибудь.

Соответствующий кандидат, насколько мой взгляд, был бы ваш public static final Parcelable.Creator CREATOR, например, так:

// Creator 
public static final Parcelable.Creator<Car> CREATOR 
    = new Parcelable.Creator<>() { 
     public Car createFromParcel(Parcel in) { 
      Car ret = new Car(in); 
      DaggerCarComponent.builder().build().inject(ret); 
      return ret; 
     } 
}; 

Цель Достигнутой с этой техникой

  • Вашего Dagger-специфический код не запутанный с вашей логикой создания экземпляра в вашем конструкторе, но как конкретная реализация un-parcelling.
  • Ваш код, специфичный для вашего кинжала, является статическим и может быть протестирован изолированно, без необходимости создавать экземпляр Car через Parcel.
  • При использовании @Component не только ваш код устойчив к будущим изменениям (например, добавление или удаление зависимостей), но и минималистский/DRY