0

I have a controller in my project which has a socket method I want to call that method in companion object.But somehow i am not able to do that as i need to pass parameters also to companion object , which i can't . Here's my code sample:

class WebSocketController @Inject() (cache:CacheApi)(implicit actorSystem:ActorSystem, materializer:Materializer) extends Controller {

def socket  = WebSocket.accept[JsValue , JsValue] { request => 
ActorFlow.actorRef(out => SocketHandlerClass.props(out,postActor))

}


}


/*My Companion Object */

object WebSocketController {

/* how to call socket method here ???*/

}
Aniket Pandey
  • 59
  • 1
  • 9
  • 1
    The companion object can be seen as a set of static vals/vars/defs. The socket function is defined on an instance of the WebSocketController. In other words, it is not possible to do this without creating an instance of the WebSocketController. – irundaia Jul 01 '16 at 10:06
  • So , how would i create the instance of WebSocktetController class with all these arguments required . Basically i want to call the socket method from another project by making this as a jar .And am not clear how to do it with companion objects in this case. – Aniket Pandey Jul 01 '16 at 10:19

1 Answers1

1

While technically possible, you shouldn't be doing that, because statically calling methods makes your code tightly coupled and defeats other benefits of dependency injection such as mocking in tests.

How you should do it: Whatever you plan to do in the companion object, do that in some other class and then inject that class.

How you could still do it with the companion object Note that this is deprecated with play 2.5 and will be removed with play 2.6, but if you really want to get an instance of that class inside the companion object, you can do this:

Play.current.injector.instanceOf[WebSocketController]

However besides this essentially defeating dependency injection, calling a controller's method from outside looks like a rather unfortunate design choice. Controllers shouldn't contain any logic - and as said above - you should extract you logic to another class an inject that into the controller.

rethab
  • 7,170
  • 29
  • 46
  • ok.But even in both the cases , i will have to call the the socket function .How it will be achieved i am not clear of? – Aniket Pandey Jul 01 '16 at 12:36
  • Only in the second (not recommended) case. Maybe you should explain what you're trying to achieve here – rethab Jul 01 '16 at 13:04
  • I am trying to use my code as a jar and use methods like socket in other projects. but i can't call the methods directly even after doing 'import'. for that if am not wrong i will have to use companion objects. the problem here is that i want to call the socket function. and i am not clear (saying it again) how to do this. – Aniket Pandey Jul 01 '16 at 13:52
  • Why would you want to call this function? Controllers are called by a client, via HTTP. If you controller contains logic, you're doing it wrong. If you have any logic that you want to share with other components (or jars, for that matter) extract that logic into some other class. – rethab Jul 01 '16 at 14:00
  • Forget the controller.If this socket function with the same body is in different class .And i want to call the same method from elsewhere, how to do that? – Aniket Pandey Jul 01 '16 at 14:56
  • What I have described is how to call an instance method from a companion method. If you don't know how to call a method as such, then that's a different question. – rethab Jul 03 '16 at 10:08