我刚开始使用 Dagger 2,想知道与我目前用来实现依赖注入(inject)的技术相比,它有什么优势。
目前,为了实现 DI,我创建了一个具有两种风格的项目:mock 和 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 类对于我需要注入(inject)的每个对象都有一个静态方法。在我的应用程序代码中,我可以简单地编写:
INetworkLayer networkLayer = Injector.provideNetworkLayer();
这对于测试非常有用,因为在我的生产代码或测试代码中,我可以简单地告诉注入(inject)器我想要什么,并且根据我使用的构建变体,注入(inject)器将为我提供生产对象或模拟测试对象。如果我希望某个对象成为单例,我只需在 Injector 类中保存对它的引用,然后在调用 Provide...() 时给出该引用。
我已经开始在一个新项目中使用 Dagger2,并发现与我上面演示的“Injector”类方法相比,设置模拟/产品依赖项要困惑得多。
Dagger 2 的做法与“注入(inject)器类”方法有何不同?
有没有好的方法使用Dagger 2来提供mock和prod类?
最佳答案
am wondering what its advantages are over a technique that I currently use to achieve dependency injection.
自动依赖图解析,以及通过添加范围注释来限定范围的提供程序。
<小时/>但是您的示例可以轻松转换为可与 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
注解在一定程度上简化您的模块。尽管在使用接口(interface)时,它并不那么明显。
@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*/;
}
}
关于java - Dagger 2 与注入(inject)器类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40752173/