2016-11-22 8 views
0

Я новичок в использовании кинжала 2 и задаюсь вопросом, каковы его преимущества в технике, которую я сейчас использую для достижения инъекции зависимостей.Dagger 2 vs Injector class

В настоящее время для достижения DI я создаю проект с двумя ароматами, издевательскими и prod. Внутри этих ароматов я создаю класс под названием Injector.

//prod Injector 
public class Injector { 
    public static INetworkLayer provideNetworkLayer() { 
     return new ProductionNetworkLayer(); 
    } 
} 

//mock Injector 
public class Injector { 
    public static INetworkLayer provideNetworkLayer() { 
     return new MockNetworkLayer(); 
    } 
} 

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

INetworkLayer networkLayer = Injector.provideNetworkLayer(); 

Это работает отлично подходит для тестирования, потому что в моем рабочем коде или тестового кода я могу просто сказать Инжектор, что я хочу, и в зависимости от того, что строить вариант я использую, тем Инжектор даст мне либо производственный объект, либо насмешливый тестовый объект. Если я хочу, чтобы определенный объект был одиночным, я просто могу содержать ссылку на него в классе Injector, а затем дать эту ссылку, когда вызывается ...().

Я начал использовать Dagger2 в новом проекте и обнаружил, что гораздо сложнее установить зависимости mock/prod по сравнению с методом класса Injector, который я продемонстрировал выше.

Каким образом Кинжал 2 отличается от метода «Инжекторный класс»?

Есть ли хороший способ использовать кинжал 2 для создания макетных и prod-классов?

+0

Ваш путь больше похож на Service Locator. Я написал [статью] (http://bayou.io/draft/In_Defense_of_Service_Locator.html), сравнивая SL и DI, в которых я также упомянул о свободе ссылок на привязку ссылок. – ZhongYu

+0

checkout https://stackoverflow.com/questions/26939340/how-do-you-override-a-module-dependency-in-a-unit-test-with-dagger-2-0 –

ответ

2

Меня интересует, что его преимущества по сравнению с техникой, которую я сейчас использую для достижения инъекции зависимостей.

Автоматическое определение графика зависимостей и охваченных провайдерами путем добавления аннотации области.


Но ваш пример может быть легко преобразован в один, который может быть использован с Dagger2, смотрите:

//prod Injector 
@Module 
public class NetworkModule { 
    @Provides 
    @Singleton 
    public static INetworkLayer provideNetworkLayer() { 
     return new ProductionNetworkLayer(); 
    } 
} 

//mock Injector 
@Module 
public class NetworkModule { 
    @Provides 
    @Singleton 
    public static INetworkLayer provideNetworkLayer() { 
     return new MockNetworkLayer(); 
    } 
} 

И

@Singleton 
@Component(modules={NetworkModule.class}) 
public interface SingletonComponent { 
    INetworkLayer provideNetworkLayer(); 
} 

И

public class Injector { 
    private Injector() { 
    } 

    private static SingletonComponent singletonComponent; 

    static { 
     singletonComponent = DaggerSingletonComponent.create(); 
    } 

    public static SingletonComponent get() { 
     return singletonComponent; 
    } 
} 

Потому что тогда вы можете сделать:

INetworkLayer networkLayer = Injector.get().provideNetworkLayer(); 


Теперь вы можете спросить: «секундочку, я уже сделал это, но теперь он занимает больше кода, чтобы настроить!»

И это потому, что вы никогда не показывали, что произойдет, если ваши зависимости зависят друг от друга.

Например,

@Module 
public class NetworkModule { 
    @Provides 
    @Singleton 
    public static INetworkLayer provideNetworkLayer(OkHttpClient okHttpClient) { 
     return new ProductionNetworkLayer(okHttpClient); 
    } 

    @Provides 
    @Singleton 
    public OkHttpClient provideOkHttpClient() { 
     return new /*create okHttpClient*/; 
    } 
} 

А также, вы можете использовать @Inject аннотацию, чтобы упростить ваши модули до некоторой степени. Хотя при использовании интерфейсов это не так очевидно.

@Singleton 
public class ProductionNetworkLayer { 
    private OkHttpClient okHttpClient; 

    @Inject 
    public ProductionNetworkLayer(OkHttpClient okHttpClient) { 
     this.okHttpClient = okHttpClient; 
    } 
} 

@Module 
public abstract class NetworkModule { 
    @Binds 
    public abstract INetworkLayer provideNetworkLayer(ProductionNetworkLayer productionNetworkLayer); 
    // same as `public INetworkLayer prov(ProductionNetworkLayer prod) { return prod; }` 

    @Provides 
    @Singleton 
    public OkHttpClient provideOkHttpClient() { 
     return new /*create okHttpClient*/; 
    } 
} 
+0

"Автоматическое разрешение графа зависимости" Означает ли это, что Кинжал может просматривать все сигнатуры методов с аннотациями @Provides и подключать правильные, чтобы возвращаемые типы некоторых методов кормили аргументы других методов? – neonDion

+1

Yup! Это точно так же, как пример «okhttpclient» выше. Но он работает с модулями до тех пор, пока они принадлежат одному и тому же компоненту, и он работает для «конкретных типов с аннотированным конструктором« @ Inject », которые либо не облагаются, либо находятся в той же области, что и компонент« – EpicPandaForce

+0

Теперь, когда я думаю об этом, то, что вы на самом деле хотите, - это привкус в этом сценарии - это класс «SingletonComponent» и привязка к нему разных модулей. Именно так вы получите свою первоначальную настройку «инжектор». – EpicPandaForce

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

  • Нет связанных вопросов^_^