0

I'm using Play! framework and I have a problem with a component injected in this controller:

public class Admin extends Controller {

    @Inject
    MenuManager menuManager;

    public Result adminHome(){
        return ok(views.html.admin_area.adminHome.render(menuManager.menuVoices()));
    }
}

The action adminHome show the homepage of my web application and I'm injecting menuManager component as a service.

This is the code for MenuManager class:

public class MenuManager {

        private ArrayList<String> voices;

        public MenuManager(){
            voices = new ArrayList<String>();
        }

        public List<String> menuVoices(){

            voices.add("Voice_1");
            voices.add("Voice_2");
            voices.add("Voice_3");

            return voices;
        }
    }

The view I'm going to render is this:

@(menuVoices: List[String])


<div>

    @for(voice <- menuVoices){
        <div>@voice</div>
    }

</div>

I can't understand the lifecycle of the injected object: menuManager.

I'll try to explain the problem. When I load the homepage I see the menu with three voices. If I reaload the page I see three more voices, this happen each time I reload the page after the first time. This happen because when I call the action adminHome() the object menuManager doesn't get re-instanced so I add the same three voices to the list before render it. A solution to this problem could be recreate the list each time I create the menu, in the method menuVoices but I don't know if this is the right way to proceed.

There is a way to force the controller to re-instance the object each time I call the action without modifying the class MenuManager? So, let's say, can I shorten the lifecycle of this object?

Thank you in advance

Ema.jar
  • 2,370
  • 1
  • 33
  • 43

1 Answers1

0

The problem is that Play controllers are singletons, as explained here:

https://stackoverflow.com/a/34867199/4600

Because of that, your MenuManager is injected just once and reused each request. Also, since you populate the menu list each time the method menuVoices is called, the list of itens will grow each time you call that method at the same instance of MenuManager. If you rewrite your service like the following, it will works as expected:

public class MenuManager {

    private List<String> voices = Arrays.asList(
        "Voice_1",
        "Voice_2",
        "Voice_3"
    );

    public List<String> menuVoices() {
        return voices;
    }
}
Community
  • 1
  • 1
marcospereira
  • 12,045
  • 3
  • 46
  • 52