Google Guice: How to inject a Scala case class which has Boolean field in its constructor - scala

I have the following issue:
I need injection for constructor a Scala case class that has fields to store different configs
This class has a Boolean attributes:
case class ConfirmConfig #Inject()(
acceptAlternativeProviders: Seq[String],
acceptManualAlternativeProvidersDisabled: Seq[String],
acceptMoveAlternativeProvidersPerProduct: Map[String, Seq[String]],
skipValidateFlownSegmentsGolMailbox: Boolean)
I am injecting this class in a service class (which has business logic) as follows:
#Singleton
class GenerateReissueMaskOperation #Inject()(
revalidationService: RevalidationService,
reservationService: ReservationService,
confirmConfig: ConfirmConfig)
When I run the app I am getting this error:
No implementation for java.lang.Boolean (with no qualifier annotation) was bound, and could not find an injectable constructor. Injectable classes must have either one (and only one) constructor annotated with #Inject or a zero-argument constructor that is not private.
at java.lang.Boolean.class(Boolean.java:43)
What is necessary to #Inject() a class which has a Boolean Scala case class argument in its constructor?
Thank you very much to anyone who can give me a hand
I am reading the official documentation (https://github.com/google/guice/wiki/) but I don't be able to resolve the problem.

Related

partial parameter list injection on play framework

given a class
class Foo #Inject()(cfg: Config, private val emr: AmazonElasticMapReduce = AmazonElasticMapReduceClientBuilder.defaultClient())
(implicit actorSystem: ActorSystem, ec: ExecutionContext)
play framework fails when it tries to Inject the 'emr' value.
I don't want play to inject it, instead I want to use the default value.
Is it possible to define?
You need to add to your Module.scala:
bind(classOf[AmazonElasticMapReduce]).toInstance(AmazonElasticMapReduceClientBuilder.defaultClient()).asEagerSingleton()
Instead of trying to provide it to the constructor.
If you don't want it injected at all, you can have it just as a member in the class.

Scala Guice how to inject configuration parameter as string?

I found the following code in Java explaining how to nicely inject your configuration parameter as annotated string parameters using guice.
https://github.com/google/guice/wiki/FrequentlyAskedQuestions
I would like to do the same thing but in scala.
How would you do it?
And note I'm looking for a solution working with generic trait/class. Something for
trait Foo[T <- SomeOtherType] {}
class FooImpl[T <- SomeOtherType](val url: String) extend Foo[T] {}
I looked into assisted injection but can't figure it out for my issue.
Any help will be much appreciated.
Thanks
You would do it in Scala exactly as you would do it in Java. First, define an annotation:
/**
* Annotates the URL of the foo server.
*/
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.FIELD, ElementType.PARAMETER})
#BindingAnnotation
public #interface FooServerAddress {}
Note that this is Java code; you cannot define runtime annotations in Scala.
Then you bind a constant annotated with this annotation:
bindConstant().annotatedWith(classOf[FooServerAddress])
And finally, you inject it:
class FooImpl[T] #Inject() (#FooServerAddress val url: String) extends Foo[T] {}
Genericity of the target class doesn't really matter here.
Also, if you use Guice with Scala, consider using scala-guice; among everything else, it allows you to omit these clunky classOfs.

How do I read/understand #Inject()... in this Scala code?

In this question, an answer says that the Application class must be defined this way:
class Application #Inject()(val messagesApi: MessagesApi) extends Controller with I18nSupport {
I understand this line as:
named Application
extends Controller
mixes in trait I18nSupport
How do I read/comprehend the #Inject() and (val ...) in the middle? Why is it written this way and what does this mean?
How do I read/comprehend the #Inject() and (val ...) in the middle? Why is it written this way and what does this mean?
#Inject() is called an annotation. Annotations allow to add arbitrary metadata to declarations, types, or expressions. This metadata can be queried either at runtime or at compiletime.
(val …) is called a primary constructor. A constructor is a subroutine which is called when you create an instance of a class, and its purpose is to set up the initial state of the object such that it is ready to use and satisfies all its invariants.

Scala AbstractSeq[A] location

http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.List
sealed abstract class List[+A] extends AbstractSeq[A] with LinearSeq[A] with Product with GenericTraversableTemplate[A, List] with LinearSeqOptimized[A, List[A]]
Where is AbstractSeq[A] location?
It's exactly where it says it is (scala.collection.AbstractSeq). However, it's a package-private class, and that's probably why it doesn't appear in the API. Here's its definition from 2.10.2:
/** Explicit instantiation of the `Seq` trait to reduce class file size in subclasses. */
private[scala] abstract class AbstractSeq[+A] extends AbstractIterable[A] with Seq[A]
In addition to Swift Tomato's answer, a bit of background - not having the AbstractSeq would mean that the Scala compiler must instantiate bridge methods for methods in Seq for every collection class that extends trait Seq. This compiler trick is needed to support multiple inheritance on the JVM.
Having all the concrete collection extend AbstractSeq allows concrete collections to inherit those bridge methods like any other JVM method, so the compiler does not need to instantiate bridge methods in every concrete collection class -- the class-file sizes of those concrete collections are reduced.
This class is private and visible only in the scala package to avoid further convoluting people's understanding of the collections package.

Scala: abstract class constructor parameter vs Trait val members?

I notice that there were several discussions about how to choose between abstract classes and traits, but it seems that none of them focused on the following point. One reason that made me use abstract classes is, they can have constructor parameters, while traits cannot. But why not the following
trait X {
def haha: Int
}
class Y(val haha: Int) extends X
and early definition is even not necessary to get everything work properly (which I worried about). The abstract class version is
abstract class X(haha: Int)
class Y(val haha: Int) extends X(haha)
and I don't like the abstract class version because, when you extend several times, these constructor parameters appear everywhere (maybe someone tells me how to avoid this?).
I am aware that abstract classes interpolate with Java better, and match the "is-a" concept more. Despite these, is there any reason that I should use abstract classes somewhere? Thanks!
The class parameter does not have to be a member (field or def).
abstract class X(haha: Int) {
val hoho = 2 * haha // compile-time constant
}
Similarly, trait initialization order depends on linearization (mix-in order), which is why trait members should be defs and not vals. (And you can always override the def with a val.) With an abstract class, you know who your supers are, and you're defining extension points for subclasses.
But note your abstract class has the val in the wrong place:
abstract class X(val haha: Int)
class Y(haha: Int) extends X(haha)
That is, you would expect X to decide if the param is a val (and it doesn't have to be). Usage of the param in either X or Y could turn it into a field.
Your observation about value params for classes also applies to type params: What a nuisance to pass Foo[A] up the hierarchy. So in Scala, we can have a member type A instead that can remain abstract until defined in a leaf. But this doesn't actually bear on whether to define a trait or a class.
But trait parameters are coming to Scala. (See the Scala bugs for early definitions which are low-priority for this reason.)