Carlos Galo Campos
Carlos Galo Campos

Reputation: 648

Creating a singleton object without an interface via Play Framework

I just heard from my Senior that I can not instantiate the concrete class as Singleton without using an interface in dependency injection even though I added the @Singleton annotation on that concrete class and it seamlessly work in the system. But doing that way, multiple instances of class is created instead, he mentioned.

I am working with Play Scala framework with Guice DI by the way.

I tried googling to verify if true but I can't find answer.

Can someone give me a concrete explanation? In java I can create a Singleton class without interface.

Upvotes: 0

Views: 773

Answers (2)

Carlos Galo Campos
Carlos Galo Campos

Reputation: 648

For the sake of keeping a record, I will post my answer.

I tried to extend the experiment of @AlexanderArendar:

import javax.inject.Singleton

/**
  * Created by Alex on 7/27/2016.
  */
@Singleton
class JustASingleton {
  def giveMeFive = "5"
}

First Controller

class MainController @Inject()(
                                environment:play.api.Environment,
                                documentService:DocumentService,
                                userService:UserService,
                                singletonInstance:JustASingleton
                              )(implicit ec:ExecutionContext)extends Controller {


  def testSingletonInjection() = Action(Ok("controller id " + System.identityHashCode(this).toString + " and Injected Bean id " + System.identityHashCode(singletonInstance).toString))
  ...

Second Controller

class SecondController @Inject()(
                                    environment:play.api.Environment,
                                    documentService:DocumentService,
                                    userService:UserService,
                                    singletonInstance:JustASingleton
                                  )(implicit ec:ExecutionContext)extends Controller {
    
    
      def testSingletonInjection() = Action(Ok("controller id " + System.identityHashCode(this).toString + " and Injected Bean id " + System.identityHashCode(singletonInstance).toString))
      ...

Then in routes

GET     /singletonX                  controllers.MainController.testSingletonInjection

GET     /singletonY                  controllers.SecondController.testSingletonInjection

And calling these 2 endpoints gave me the following results:

controller id 1944357758 and Injected Bean id 853668078

controller id 943948501 and Injected Bean id 853668078

As I can conclude based on the test, that the concrete class can be created as Singleton without having to provide an Interface

Upvotes: 0

Alexander Arendar
Alexander Arendar

Reputation: 3435

If what you mean is whether it is possible to inject a class right away without a "companion" train and binding trait to implementation in Module then it is possible. I have just experimented. Here goes my simple class: package services

import javax.inject.Singleton

/**
  * Created by Alex on 7/27/2016.
  */
@Singleton
class JustASingleton {
  def giveMeFive = "5"
}

Then in my controller I am injecting it without any trait (interface as you called it):

class MainController @Inject()(
                                environment:play.api.Environment,
                                documentService:DocumentService,
                                userService:UserService,
                                singletonInstance:JustASingleton
                              )(implicit ec:ExecutionContext)extends Controller {


  def testSingletonInjection() = Action(Ok(singletonInstance.giveMeFive))
  ...

Then in routes I have the line:

GET     /singleton                  controllers.MainController.testSingletonInjection

It compiles ok and when I go to localhost:9000/singleton then i get a proper html response. So injection without a trait and binding an implementation to a trait does work.

Upvotes: 1

Related Questions