How can I access request in Play Guice Module?

瘦欲@ 提交于 2020-01-24 09:10:06

问题


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.


回答1:


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:

object CustomerService {
  trait Factory {
    def apply(val systemID: String): CustomerService
  }
}

2. Implement your service with the assisted parameter

class CustomerService @Inject() (@Assisted systemId: String) { .. }

3. Bind the factory in your guice module:

install(new FactoryModuleBuilder()
  .implement(classOf[CustomerService], classOf[CustomerServiceImpl])
  .build(classOf[CustomerService.Factory]))

4. And finally inject the factory where you need the customer service:

class MyController @Inject() (csFactory: CustomerService.Factory) { .. }

Here's another example of assisted inject: https://www.playframework.com/documentation/2.5.x/ScalaTestingWebServiceClients



来源:https://stackoverflow.com/questions/35960207/how-can-i-access-request-in-play-guice-module

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!