Hi Vlad

Ok not sure if I understood everything you asked. But we will get you there.

I assume that your code looks something like this:

public static void main(String[] args) {
    // ...
    pool = new ThreadPoolExecutor();
    pool.run(new CustomTask());
    pool.run(new OtherTask());
    pool.run(new ImportantTask());
}

All the tasks would know about the StatsService singleton. So no need to pass the instance to the constructor.

Now with dependency injection it is a little different:

public static void main(String[] args) {
    // ...
    injector = Guice.crateInjector(new SomeModule());
    pool = new ThreadPoolExecutor();
    pool.run(injector.getInstance(CustomTask.class));
    pool.run(injector.getInstance(OtherTask.class));
    pool.run(injector.getInstance(ImportantTask.class));
}

The big difference is, that all the "new" are gone. Creating the instances is now handled by Guice.
--
Side note: usually calling "injector.getInstance()" is a code smell since you should have your dependencies injected and not retrieve them form the injector (see: DI vs. ServiceLocatorPattern).
In the main class (or method) it is legitimate since you need some entry point into your application.
--

Now the second thing that changes are the tasks:
With the singleton pattern they have no member variable holding the StatsService.
In the dependency injection approach each Task will have an instance variable holding the StatsService (or a variable holding a provider for the stats service).

public class CustomTask {

    private final StatsService statsService;
    private final OtherService otherService;

    @Inject
    public CustomTask(StatsService statsService, OtherService otherService) {
        this.statsService = statsService;
        this.otherService = otherService;
    }

    // ...
}

Since all the instances passed to the constructor are created by Guice the CustomTask does not need to worry about the dependencies of the OtherService.
If the OtherService also has a dependency onto the StatsService it will declare it in its constructor.

In your question you wrote that CustomTask "initializes" other Objects. In the best case they can be injected into the constructor like OtherService in the code sniped above.
If you need to get "fresh" instances on demand you can have an Provider<SomeHelper> injected and call the provider.get() method whenever you need an instance.

This should get you 90% of the way. But in some cases you need to pass both runtime data and dependencies into an object.
Here is an example:

public class SomeHelper {

    private final StatsService statsService;
    private final String userName;

    @Inject
    public SomeHelper(String userName, StatsService statsService) {
        this.userName = userName;
        this.statsService = statsService;
    }

    // ...
}

In such a situation Guice provides the assisted inject extension which allows you to define an interface to pass the runtime data (like userName) and have Guice take care of the rest.
http://code.google.com/p/google-guice/wiki/AssistedInject

So I hope this should get you going if not just come back and rephrase your question.






On 04/19/2014 11:03 PM, [email protected] wrote:
Hi,

I have following scenario - rather usual use of Singletons which I'd like Inject with Guice.

There is StatsService which is currently implemented using Singleton Pattern and has a state. I receives data from various places and sends them over separate Thread which is constantly running. This runs throughout entire lifecycle of the application.

In the App there are multiple Threads executing various tasks. Each Runnable Object posts internal metrics to StatsService.getInstance().increament(1);

pool = new ThreadPoolExecutor();
pool.run(new CustomTask());

Do I have to inject StatsService into a constructor of every object I create starting from Main class? Or is there a way any instance can lookup Guice Singleton Instance and use it? I could just simply inject CustomTask with StatsService instance but if CustomTask initializes some other Object which needs to have access StatsService then we need to inject the inherited objects as well - kind of a chain which I don't really like to see. 

What would be the correct design choice to organize code and take advantage of Singleton instance for this reporting purpose?

Thanks,
Vlad
--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice.
For more options, visit https://groups.google.com/d/optout.

Reply via email to