I am writing an application which handles multiple systems. The user can choose the system which he wants to work with and I store that system ID in session (client session)
Now I have Service classes, lets say CustomerService.
class CustomerService(val systemID: String) {
// Implementation
}
I want to use Guice to inject the Customer instance to the Controllers. But I want to instantiate the CustomerService with SystemID which is stored in the session.
How can I access request.session
in Guice Module?
Edit:
Had simplified my code above. My actual code uses interfaces. How can I use assisted inject for this?
trait CustomerService(val systemID: String) {
// Definition
}
object CustomerService{
trait Factory {
def apply(systemID: String) : CustomerService
}
}
class DefaultCustomerService @Inject() (@Assisted systemID: String)
extends CustomerService {
// Definition
}
class CustomerController @Inject()(
val messagesApi: MessagesApi,
csFactory: CustomerService.Factory)
{
}
This gives me: CustomerService is an interface, not a concrete class. Unable to create AssistedInject factory.
And I do not want to put the Factory under DefaultCustomerService
and use DefaultCustomerService.Factory
in the controller. This is because for unit testing I will be using TestCustomerService
stub and want Dependency Injection to inject TestCustomerService
into the controller instead of DefaultCustomerService
.
You should not do that. If you need to inject an instance of something that requires runtime-values, you can use guice's AssistedInject.
Here's how you can use it with play:
1. Create a factory of your service with the runtime value as parameter:
2. Implement your service with the assisted parameter
3. Bind the factory in your guice module:
4. And finally inject the factory where you need the customer service:
Here's another example of assisted inject: https://www.playframework.com/documentation/2.5.x/ScalaTestingWebServiceClients