0

I have a class that should be injected in two different ways:

  1. for general purpose as singleton

  2. customized version as RequestScoped.

Example:

public class TaskProcessorService implements TaskProcessor {
    private final TaskRegistry taskRegistry;
    @Inject
    public TaskProcessorService(TaskRegistry taskRegistry){
        this(taskRegistry, null);
    }
    @AssistedInject
    public TaskProcessorService(TaskRegistry taskRegistry, @Assisted String userId) {...}

    public synchronized void performTask(){...}
}

Let's say everybody can use general purpose object and compete for performTask operation (since it's synchronized), or they can invest and create it's own instance/instances.

For general purpose i've created interface

public interface TaskProcessor{
     void performTask();
}

and binding:

bind(TaskProcessor.class).to(TaskProcessorService .class).in(Singleton.class);

and for customized version i've created factory

public interface TaskProcessorFactory{
    public TaskProcessor(@Assisted String userId);
}

and installed it:

install(new FactoryModuleBuilder()
 .implement(TaskProcessorService.class, TaskProcessorService.class)
 .build(TaskProcessorFactory.class));

I've tried it and it worked in runtime(I hope that I didnt make mistakes writing above pieces of code by hand), hovewer I'm not sure if it works fully as I wanted since I just wrote it and doesnt had time to fully test it yet.

But then i realized that i don't know how the factory works. For different users ('userId') it should create different instances, but what about same userId? Let's say some John Doe want to create 3 instances of TaskProcessorService, will the factory create 3 different instances for each call (assuming parameter will be same - john doe's ID)?

That's the main question, does the factory always create new objects even for calls with the same parameters? Couldn't find any proof about it in docs, and i'm not 100% sure if some caching mechanism was not created.

And second issue, is it optimal solution for the problem?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Rychu
  • 86
  • 1
  • 7

1 Answers1

0

Answer to your first question is yes. In your case it will always create different objects. For second question continue reading.

It is incorrect to have 2 bindings referring to the same interface. In case of of an object with 2 constructors, you annotate them both with @AssistedInject and in the factory, you need 2 methods reflecting those constructors. Then just install it using the FactoryModuleBuilder.

Nektie
  • 94
  • 9
  • Thx for the first part. About the FactoryModuleBuilder - i believe you cannot force singleton instance out of first constructor. Finally about 2 bindings - technically it's true what you've said, my solution expose them(not directly but still), on the other side you can inject the interface no problem and I cannot find better solution. – Rychu Mar 07 '17 at 18:31
  • Is that a requirement that you have to provide singletons from the first constructor? If yes, then you can write a custom factory and bypass Guice AssistedBinding alltogether. – Nektie Mar 07 '17 at 22:01