Is it possible to create one singleton object, and being able to inject it independently as the one instance, or as a part of set or map?
For example, I have two instaces like this:
@Provides
@Singleton
@Named(value = "bike.listener")
fun bikeListener(
mapper: ObjectMapper,
amazonSNS: AmazonSNS,
kafkaPublisher: KafkaPublisher
): PublishingListener {
return PublishingListener(
mapper = mapper,
amazonSns = amazonSNS,
kafkaPublisher = kafkaPublisher
)
}
@Provides
@Singleton
@Named(value = "car.listener")
fun carListener(
mapper: ObjectMapper,
amazonSNS: AmazonSNS,
kafkaPublisher: KafkaPublisher
): PublishingListener {
return PublishingListener(
mapper = mapper,
amazonSns = amazonSNS,
kafkaPublisher = kafkaPublisher,
)
}
... and I use them in my classes by directly injecting them via @Named
parameters. But, I also have a use case where I want to inject both of them in a set.
So something like:
@Inject
Set<PublishingListener> listeners; // carListener and bikeListener here
Is it possible to create MultiBinder
which would use the already defined instances? How can I use the same instance in the set, and separately?
In your Guice Module, you can bind those instances to a set like this:
@Provides
fun publisherListenerSet(
@Named("car.listener") val carListener: PublisherListener,
@Named("bike.listener") val bikeListener: PublisherListener
): Set<PublisherListener> {
setOf(carListener, bikeListener)
}
Or you can use:
protected override fun configure() {
val publishingListenerSetBinder = Multibinder.newSetBinder(binder(), PublisherListener::class.java)
publishingListenerSetBinder.addBinding().annotatedWith(Names.named("car.listener"))!!.to(PublishingListener::class.java)
publishingListenerSetBinder.addBinding().annotatedWith(Names.named("bike.listener"))!!.to(PublishingListener::class.java)
}
As you don’t actually call the provider method, the Injector can maintain the singleton-ness of the thing that the provider provides.