Keeping AppModule as a Singleton - java

In my application (standalone), when I need to get some object instance from Guice, I usually do it like this:
injector = Guice.createInjector(new AppModule());
instance = injector.getInstance(MyInterface1.class);
I was wondering:
Why do I need to pass an instance of the AppModule class, and not the module class reference itself, so Guice could instantiate it?
What side-effects should I expect if I keep my AppModule class as a singleton, therefore always using the same instance when calling Guice.createInjector()?
As a side note:
What about the Injector itself? How bad design would it be if I keep just one instance of it somewhere?

Passing an instance to createInjector allows you to configure the module to your liking via constructor parameters. Guice does not mutate the Modules so you could keep them around, but a better practice is what you're already doing: create a single Injector and bootstrap your application from there. As your application grows you'll write more modules and you don't want to manage that complexity yourself.
You shouldn't have to maintain a reference to the Injector because you can always just inject it, although there are a limited number of cases where this is appropriate. It makes more sense to inject the actual dependencies into your class. This makes the dependency hierarchy clear and your code much more testable.

Related

Is there a way to access Guice injectors which have previously been created?

Taking a look at Guice (and Dagger) for a new project. Every Guice tutorial I have seen so far shows an injector being created at the point where the developer needs the DI to create an object instance.
A typical example seen on the web:
public static void main(String[] args) {
Injector injector = Guice.createInjector(new BasicModule());
Communication comms = injector.getInstance(Communication.class);
}
To me this defeats the purpose of the DI - everywhere an instance is required, you tie the instance to the modules which define how to build it.
Is there a way to ask Guice to create an instance of a class who's module (dependency graph) has been previously defined to Guice (eg. at application startup?).
I am using the Dropwizard.io framework so there are situations where I don't have full control over the way a class is constructed but want to be able to mock out the dependencies I reference in that class.
Exactly the same applies to Dagger - I'd appreciate examples for either/both.
Edit:
I've worked with several DI frameworks in .NET over the years, so I'm going to give an example of what I'm trying to do based on one of those.
For example, in the ASP.NET Core DI implementation, at service start-up you define the services you want the DI to be able to create. Typically you'll be asking the DI to give you an instance which is an implementation of an interface. So at start-up:
protected override void ConfigureAdditionalServices(IServiceCollection services)
{
services.AddScoped<ITransactionService, TransactionService>();
}
where IServiceCollection is the collection of services defined to the DI.
Because the DI is integrated with the ASP.NET framework, from this point on you can generally define a constructor which takes ITransactionService and the DI will provide it for you.
However, if you were using the DI in a framework which did not know about it, you'd need access to the current ServiceProvider instance, and then you could ask the DI to create your object like this:
var transactionService = ServiceProvider.GetService<ITransactionService>();
I realise that this implemeting the Service Locator anti-pattern but it still has the benefit of decoupling my code from the concrete class implementations and allowing me to mock them out for testing at application start-up.
So back to the question
So to restate my question in the light of this context, how can I request a class from Guice at some random point in my code?
What would I need to change in this code to make it work?
public class TransactionModule extends AbstractModule {
#Override
protected void configure() {
bind(TransactionServiceBase.class).to(TransactionService.class);
}
}
// At startup
Injector injector = Guice.createInjector(new TransactionModule());
// Then, somewhere in the application, to get an instance of TransactionService
TransactionServiceBase transactionService = (TransactionServiceBase)Guice.getInstance(TransactionServiceBase.class);
I think you might be misunderstanding Injector.getInstance - in the same way that your example has a public static method to start things off, even though you don't usually write the rest of your app with all public static methods (I hope), you also don't call Injector.getInstance except in a very few specific cases.
Instead, this code is just used to get things going. Another popular "get this started" is injector.injectMembers(this) - let the main() create an instance manually of whatever is the basis of your application, with #Inject-annotated members, and then just ask the now-created Injector to populate the members.
As you continue "inward" to the rest of your application, you likely will never reference the Injector instance again, but instead rely on providers, assisted inject, or just guice-created instances.
In this way, you should never care about the Injector or the exact modules that were set up for it. Only one Injector should exist over the lifetime of the app (there are essentially no exceptions to this, except perhaps if you redefine what an "app" is), and 99% of the time it is hidden from you (exceptions: where your DI meets some other DI, and needs to request an instance of something by its Class, or where you have tooling that wants to introspect the set of all declared bindings). As such, you should be able to just provide setters, constructor args, or init methods, and then can call them manually, or have any guice context create them based on their own specific modules and rules.
I think that the answer is that there is no standard/supported way to do that.
The usual assumptions is that you have as few 'injections' points as possible, ideally one, and then you specify what each class needs by making dependencies constructor arguments.
The only scenario I know well similar to what you describe here is Dagger in android apps. The way they solved it is that they store the dagger "Injector" (sorta) in a global object - the Application, and then Dagger provides a static function to retrieve that object and perform the injections.
Long story short DI frameworks don't play well with paradigms where you don't instantiate classes yourself.
And the only solution I can think of is storing your injector in some global variable and get it from there when you need it.
Static injection might help to some degree in your case
https://github.com/google/guice/wiki/Injections#static-injections

DI with arguments in the constructor

So I'm implementing a Dependency Injection framework into my Java project (Google Guice) and everything is pretty good, I like it but there's a small problem;
I want to make a static instance of my main project's class (where it instantiates the dependencies, etc). But I don't know any method to instantiate it using Guice, I can't instantiate it manually because I'm using DI in the constructor of it (I have objects in the constructor) which means that I am not able to access the class' non-static variables needed to instantiate the class.
I tried using a Provider but I couldn't really understand where to bind it, because I don't want to have an interface for the main class (will if needed).
If you are wanting to mix a static instance of a class with dependency injection, you have somewhat missed the point of dependency injection: you can simply inject the instance of the class.
If you want there to be a single instance of a class for your injector, bind it in #Singleton scope: either:
bind(YourClass.class).in(Singleton.class);
in your module's configure() method, or
#Provides #Singleton YourClass provideYourClassInstance() {
// ...
}
in your module, or
#Singleton class YourClass {
// ...
}
in the actual class declaration.
Then just inject this instance like any other:
class SomeOtherClass {
#Inject SomeOtherClass(YourClass instance) {
// ... Do something with instance, like assign it to a field.
}
}
The point is that SomeOtherClass shouldn't need know anything about the lifetime of instance: it simply doesn't matter whether this is a singleton instance, or every class using it has its own instance.
You can get three different answers here depending on the question.
To directly answer the question in the title (DI with arguments in the constructor), you can mix DI with constuctor arguments by instead injecting a Factory. Though you're welcome to write one manually, Guice can do this for you as assisted injection (see FactoryModuleBuilder), or you can use the equivalent code-generated solution AutoFactory popular through Dagger.
If you're trying to initialize a static class's fields in a Guice application, Guice can do that for you as soon as the Injector is created. Simply call requestStaticInjection in a Module you feed to Guice. This, as Andy Turner pointed out, will cause you to miss out on some of the benefits of Guice: Because you're injecting the instance statically, there's very little opportunity for you to provide replacement implementations in tests or in other class reuse. Guice describes this more in the static injections section of its wiki:
When migrating an application from static factories to Guice, it is possible to change incrementally. Static injection is a helpful crutch here. It makes it possible for objects to partially participate in dependency injection, by gaining access to injected types without being injected themselves. [...]
Static members will not be injected at instance-injection time. This API is not recommended for general use because it suffers many of the same problems as static factories: it's clumsy to test, it makes dependencies opaque, and it relies on global state.
The best overall solution is in Andy's answer: Adapt your application to use DI, which will let it inject the objects that you would otherwise make static.

Do Guice #Singleton have to follow the Singleton design pattern?

Do classes annotated with #Singleton have to follow the Singleton design pattern?
My guess is that they do not: it is not necessary to have a private constructor, and a static .instance() method, but instead it is Guice that makes sure that only one instance of the class will be instantiated.
Not only are they not required to follow the Singleton pattern, they explicitly should not follow it.
A system that is properly set up with Guice should be creating as few of its own objects as possible, instead letting the framework do all of the object creation. Further, you do not want random classes in your system to be calling .instance() on this static instance, and, finally, you do not want Guice to be creating a static reference in the Singleton class using .requestStaticInjection().
The right thing to do with your #Singleton classes is to just have them be injected into the classes that need that particular dependency.
The difference between a singleton in Guice and the regular singleton has to do with context.
When you're not using Guice you have to manage your singleton yourself. To ensure that there is only ever one instance created you have a private constructor, a static field and methods to access this instance (either a getter or making the field final). This means that the instance is a singleton in the context of the class loader. If you create another class loader and tell it to load your singleton class you can create a second instance.
When the singleton is managed by Guice we replace the private constructor and static field with the #Singleton annotation, telling the injector that it should only ever create one instance of this class and use it anywhere it is requested. Since it is possible to have more than one injector simultaneously (either because you need two completely different contexts or because you're using child injectors) you must not prevent Guice from instantiating more than one instance of your class.
Additionally, since you should rely on Guice to provide the singleton everywhere it is required there is no need for a static field containing the singleton instance since it should never be accessed.

Instantiating per-scope/group singletons - stuck in Guice dependency hell

This question is a continuation of Using guice for a framework with injected classes, proper way to initialize?, which I've tried to implement, and also tried other ways to get around the issue, but nothing has worked so far.
The main issue is this. I have an InterfaceA and InterfaceB that are exposed in different parts of the API. There are two classes that implement both of these interfaces, TestClass and RealClass, so that depending on whether I'm testing or doing something else, I can do the following:
bind(InterfaceA.class).to(TestClass.class);
bind(InterfaceB.class).to(TestClass.class);
or, for production:
bind(InterfaceA.class).to(RealClass.class);
bind(InterfaceB.class).to(RealClass.class);
I have two requirements for using these classes:
I need the same instance of TestClass or RealClass to be bound to all injections of InterfaceA and InterfaceB; so, like a singleton pattern, except that:
The singleton is only for a specific scope or child injector, many of which are created during the execution of the program.
The default no-scope approach causes multiple instances of RealClass/TestClass to be created for each interface injection. I don't want that, so I've tried implementing this with scopes, child injectors, and other methods. Nothing has worked:
Child injector approach: I create a new injector and try to bind the TestClass or RealClass to a singleton instance in that injector. The problem is, whether TestClass or RealClass is being used is configured in the parent injector, and since it's a singleton, it's already instantiated (unless in Stage.DEVELOPMENT). There's no way to bind InterfaceA to TestClass, in the parent injector, for example, and then re-bind it as a singleton in the child injector.
Scope approach: I create a custom scope and annotate TestClass and RealClass. Then, I enter and exit this scope to get single instances in that scope. The problem is that my code is multithreaded and having the scope change from one thread affects what the global injector can see and mucks up creating other instances.
Combined child injector and scope approach. I tried creating a child injector for each use of this custom scope, but then binding RealClass in the parent fails with
No scope is bound to name.package.WhateverScope.
because it seems to insist that the WhateverScope is available all the time, not just in the child injector.
All these problems seem to be due to the fact that I need to be able to configure whether to use TestClass or RealClass in the parent, but then to be able to instantiate them later, as a singleton, for a specific group of objects. I'm pulling my hair out over how to get this done!
By the way, the documentation for Guice scopes is horrible and almost impossible to understand. This article is the only one that has gotten me anywhere:
Apologies for a somewhat-breakthrough less than an hour after posting.
I seem to have been able to fix this by somewhat abusing the thread-local scope implementation provided at http://code.google.com/p/google-guice/wiki/CustomScopes. It seems to be a somewhat clean way to solve this problem without using child injectors. I'm not sure if it's 'proper', though. I'll still accept other answers.
Here's what I did. First, I create one instance of the scope, bind it to the appropriate annotation, and make it available in the injector:
ThreadLocalScope scope = new ThreadLocalScope();
bindScope(ExperimentScoped.class, scope);
bind(ThreadLocalScope.class).toInstance(scope);
Then, as the documentation says, I need to bind a fake provider for every type of key that would be seeded in the scope:
bind(SomeKey.class)
.toProvider(ThreadLocalScope.<SomeKey>seededKeyProvider())
.in(ExperimentScoped.class);
bind(SomeOtherKey.class)
.toProvider(ThreadLocalScope.<SomeOtherKey>seededKeyProvider())
.in(ExperimentScoped.class);
I may also have some other scope-able objects that I want to be distinct within each scope, so I bind those too. These are the TestClass and RealClass above. There may be also SomeScopedClass that was annotated with the #ExperimentScoped:
bind(InterfaceA.class).to(TestClass.class).in(ExperimentScoped.class);
bind(InterfaceB.class).to(TestClass.class).in(ExperimentScoped.class);
bind(SomeInterface.class).to(SomeScopedClass.class);
Finally, I can use the scope to create distinct sets of interdependent objects, in parallel from different threads. Each thread can do something like the following, even though they are using the same injector:
ThreadLocalScope scope = injector.getInstance(ThreadLocalScope.class);
scope.enter();
try {
// Seed the seed-able keys
scope.seed(SomeKey.class, keyInstance);
scope.seed(SomeOtherKey.class, otherKeyInstance);
SomeScopedClass instance = injector.getInstance(SomeScopedClass.class);
// Hooray! instance was injected with the seeds and created just for this scope!
}
finally {
scope.exit(); // Throws away the scope and referenced objects.
}
In my case, I can discard the scope completely because I don't care about keeping track of the set of objects in the scope once they're wired up properly. But it probably wouldn't work if I wanted to come back to this scope later and inject some more objects.
Hope this helped someone. The Guice scoping documentation is terrible!

Difference between creating new object and dependency injection

What is the difference between creating a new object and dependency injection? Please explain in detail.
Well, they're not exactly comparable. You will always have to create a new object by instantiating a class at some point. Dependency injection also requires creating new objects.
Dependency injection really comes into play when you want to control or verify the behavior of instances used by a class that you use or want to test. (For Test Driven Development, dependency injection is key for all but the smallest example).
Assume a class Holder which requires an object of class Handle. The traditional way to do that would be to let the Holder instance create and own it:
class Holder {
private Handle myHandle = new Handle();
public void handleIt() {
handle.handleIt();
}
}
The Holder instance creates myHandle and no one outside the class can get at it. In some cases, unit-testing being one of them, this is a problem because it is not possible to test the Holder class without creating the Handle instance which in turn might depend on many other classes and instances. This makes testing unwieldy and cumbersome.
By injecting the Handle instance, for example in the constructor, someone from the outside becomes responsible for the creation of the instance.
class Holder {
private Handle myHandle;
public Holder(Handle injectedHandle) {
myHandle = injectedHandle;
}
public void handleIt() {
handle.handleIt();
}
}
As you can see the code is almost the same, and the Handle is still private, but the Holder class now has a much loser coupling to its outside world which makes many things simpler. And when testing the Holder class a mock or stub object can be injected instead of a real instance making it possible to verify or control the interaction between the Holder, its caller and the handle.
The actual injection would take place at some other place, usually some "main" program. There are multiple frameworks that can help you do that without programming, but essentially this is the code in the "main" program:
...
private Handle myHandle = new Handle(); // Create the instance to inject
private Handler theHandler = new Handler(myHandle); // Inject the handle
...
In essence, the injection is nothing more than a fancy set method. And of course, you can implement the injection mechanism using that instead of in the constructor like the simple example above.
Of course, both create objects. The difference is in who is responsible for the creation. Is it the class that needs its dependencies or a container like Spring for example, which wires the component's dependencies? You configure the dependencies in a separate(typically XML) configuration file.
It is really a separation of concerns. The class says I need this, this, and this component to function properly. The class doesn't care how it gets its components. You plug them into the class with a separate configuration file.
To give you an example let's consider having a shopping class that needs a payment module. You don't want to hardcode which payment module will be used. To achieve this you inverse the control. You can change the used payment module with a few keystrokes in the configuration file of the container. The power is that you aren't touching any Java code.
Well,
creating a new object is as explicit as it can get - you create a new instance of the desired class.
Dependency injections is a mechanism that provides you with references where you need them.
Imagine a class that represents a connection pool to your database - you usually only have one instance of that class. Now you need to distribute that reference to all the classes that use it.
Here is where Dependency Injection comes in handy - by using a DI framework such as Spring you can define that the one instance of your pool will be injected into the classes that need it.
Your question itself is not easy to answer since the creation of an object and dependency injection can't be compared that easily...
Dependency injections adds a layer of configurability into your application. In the sense, when you hard code object construction, you need to re-build and re-deploy your app, but when you use dependency injection, you can re configure the XML and change the behavior without re-building and re-deploying. There are a large variety of use cases where this can save a lot of tie and effort.
When using an inversion-of-control container to perform dependency injection, the container creates the objects, and not the developer. This is done so that the container can "inject" these objects into other objects.
The answer to the following question may also give the answer you are looking for: Why is the new operator an anti-pattern? Well, the simple answer is that using the new operator may create a hidden, inaccessible dependency within the containing class. This makes testing the containing class more difficult because it involves testing the hidden dependency at the same time (barring MOCK frameworks of course). However, you can avoid this situation by not using the new operator and injecting the dependent object instead. This also has the following advantages:
For test purposes you can inject a different object.
The resulting containing class is more reusable because it can support different implementations of the dependent object.

Categories