Reputation: 1145
I'm having an issue with Dagger2 that is the following:
I have a XML Serializer that receives a Format, a Strategy and a Matcher. My issue is that the format can be one of the following:
new Format()
new Format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
My way to fix this was to create Qualifier interfaces as following:
@Qualifier @Retention(RUNTIME) public @interface NoFormat {}
@Qualifier @Retention(RUNTIME) public @interface WithFormat {}
[Edit:] // @Qualifier @Retention(RUNTIME) public @interface FormatSerializer {} <- This was unecessary
[Edit:] // @Qualifier @Retention(RUNTIME) public @interface NoFormatSerializer {} <- This was unecessary
And then specify different implementations of each qualifier:
@Provides @Singleton @WithFormat Format provideWithFormat() {
return new Format(XML_PROLOG);
}
@Provides @Singleton @NoFormat Format provideNoFormat() {
return new Format();
}
@Provides @Singleton @WithFormat
Serializer provideFormattedSerializer(Strategy strategy, @WithFormat Format format,RegistryMatcher matcher) {
return new Persister(strategy, matcher, format);
}
@Provides @Singleton @NoFormat
Serializer provideNoFormatSerializer(Strategy strategy, @NoFormat Format format,RegistryMatcher matcher) {
return new Persister(strategy, matcher, format);
}
@Provides @Singleton
Retrofit provideRestAdapter(@WithFormat Serializer serializer) {}
@Provides @Singleton
XmlApiSerializer provideXmlApiSerializer(@NoFormat Serializer serializer) {}
Is this the correct approach? I feel it's too much.. I tried different approaches but I was never able to inform dagger which implementation he should use for each case. This was my only "success" case.
What are your thoughts about this? Could it be improved? How?
Edit: I realized I was using 2 qualifiers that weren't needed. Now I only have the withformat and noformat qualifier
Upvotes: 2
Views: 87
Reputation: 3762
You can create small graphs of related objects by delegating to separate components. Here's how it might look just dealing with the Format
and the Serializer
.
@Component(modules = {FormatModule.class, SerializerModule.class})
interface SerializerHelperComponent {
Serializer serializer();
}
@Module
final class FormatModule {
private final Format format;
FormatModule (Format format) {
this.format = format;
}
@Provides Format format() {
return format;
}
}
@Module
final class SerializerModule {
/** This @Provides method doesn't need the qualifier! */
@Provides static provideSerializer(
Strategy strategy,
Format format,
RegistryMatcher matcher) {
return new Persister(strategy, matcher, format);
}
}
Now, in your original @Provides
method, you can just create a new helper component to wire up everything with the format that you choose.
@Provides @Singleton @WithFormat
Serializer provideFormattedSerializer(
Strategy strategy,
Format format,
RegistryMatcher matcher) {
return DaggerSerializerHelperComponent.builder()
.formatModule(new FormatModule(return new Format())
.build()
.serializer();
}
With only one binding, this is definitely not worth the trouble, but if there is a complicated graph that would be created in the helper component in order to get the output, it might be worth it. This is definitely a judgement call.
Upvotes: 1