Dagger 2 - what is the purpose of a #Singleton annotation class - dependency-injection

From the dagger 2 Documentation I noticed that you can have a #Singleton annotated class. What is the purpose of marking a class as #Singleton as I have tried to do this in my code but a singleton object is NOT produced. I'm not clear on what use marking my class with this annotation serves.
From the documentation please focus on the following statement:
The #Singleton annotation on an injectable class also serves as
documentation. It reminds potential maintainers that this class may be
shared by multiple threads.*
#Singleton
class CoffeeMaker {
// ...
}
UPDATE: After reviewing froger_mcs answer I see that in Dagger 2 you can provide injections either by a module OR by a constructor injection. So the following class, although not in a module, can be injected:
#Singleton
public class MyClass {
#Inject
public MyClass() {
}
}
In this version the constructor is injected for us and in an Android activity you would just do the following and it will get provided:
#Inject
MyClass myClass;
//then in onCreate actually inject(this) from your graph of course.

#Singleton (and any other scope annotation) makes your class a single instance in your dependencies graph (it means that this instance will be "singleton" as long as Component object exists).
In short - everytime you're injecting #Singleton annotated class (with #Inject annotation) it will be the same instance as long as you inject it from the same Component.
For more I'm referring my blog post about how #Singleton and other scopes annotations works in Dagger 2: http://frogermcs.github.io/dependency-injection-with-dagger-2-custom-scopes/

#Singleton does not really create a Singleton, it is just a Scope, it is advised to not use #Singleton as it is misleading, it gives the impression that we are infact getting a Singleton, but we are not.
Let's say you annotate your database dependency with #Singleton and link with a Component, now let's say that you initialise this Component in Activities A and B, you will have different instances of your database in your two Activities which is something most people don't want.
How do you overcome this?
Initialise your Component once in your Application class and access it statically in other places like Activities or Fragments, now this could soon get out of hand if you have more than 20 Component's as you cannot initialise all of them in your Application class, doing so will also slow down your app launch time.
The best solution according to me is to create a real Singleton, either double checked or of other variants and use this statically as getInstance() and use this under #Provides in your Module.
I know it breaks my heart too, but please understand that #Singleton is not really a Singleton, it's a Scope.

What is singleton?
Singleton Pattern in android
A single instance of a class providing a global point of access to itself during the entire application's lifetime.
#Singleton annotation in Dagger
A single instance of a class which is unique to a specific component, its access is limited to the scope of the component.
Purpose of singleton
To provide a single instance of a class within the dependency graph(component). a component is usually initialized in the application level as it executes only ones for the entire applications lifetime and is accessible by all activities and fragment.
Let's take an example:
CoffeeComponent.kt
#Singleton
#Component
interface CoffeeComponent {
fun getCoffeeMaker():CoffeeMaker
fun inject(activityA: ActivityA)
fun inject(activityB: ActivityB)
}
CoffeeMaker.kt
#Singleton
class CoffeeMaker #Inject constructor()
CoffeeAplication.kt
class CoffeeApplication : Application() {
private val component by lazy {
DaggerCoffeeComponent.builder().build()
}
fun getAppComponent(): CoffeeComponent = component
}
Recommended Practise
Always go for lazy initialization of your component.Scenario: say, you are team decided to add an onboarding/tutorial screen or incorporate some other design which doesn't require the component during the initial screens, it will help minimize the startup delay. Always remember, component initialization is expensive.
ActivityA.kt
import dagger.Lazy
class ActivityA: AppCompatActivity() {
#Inject
lateinit var coffeeMaker1:Lazy<CoffeeMaker>
#Inject
lateinit var coffeeMaker2:Lazy<CoffeeMaker>
private val component by lazy {
(application as CoffeeApplication).getAppComponent()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btn_activityB.setOnClickListener { startActivity(Intent(this, NewActivity::class.java)) }
component.inject(this)
println("Activity A CoffeeMaker 1 - ${coffeeMaker1.get()}")
println("Activity A CoffeeMaker 2 - ${coffeeMaker2.get()}")
}
}
If your class is expensive to construct, use the dagger's Lazy initialization, please don't confuse it with kotlin's Lazy. You have to import
import dagger.Lazy
#Inject
lateinit var coffeeMaker1:Lazy<CoffeeMaker>
ActivityB.kt
class ActivityB: AppCompatActivity() {
#Inject
lateinit var coffeeMaker1:Lazy<CoffeeMaker>
#Inject
lateinit var coffeeMaker2:Lazy<CoffeeMaker>
private val component by lazy {
(application as CoffeeApplication).getAppComponent() }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_new)
component.inject(this)
println("Activity B CoffeeMaker 1 - ${coffeeMaker1.get()}")
println("Activity B CoffeeMaker 2 - ${coffeeMaker2.get()}")
}
}
you will get the Log output as
Note:
If you want to share a singleton instance between activities, lazily initialize them in the application level, if you initialize them in an activity you will end up with different instance as the components are different

Well you can manually create an annotation,which will help to create a singleton object.
#Scope
#Retention(RetentionPolicy.CLASS)
public #interface MyApplicationScope {
}
When #MyApplicationScope annotation is added with #Provides annotation than it makes dagger to create an object only once and use same object in future. Do remember to add this annotation to the component interface also otherwise you will get the scope related error during compilation.
If you are using #Singleton annotation then you may end up creating the new objects every time when you will create your component with .build().

#Singleton is inherit #Scope, so in documentation says
Identifies scope annotations. A scope annotation applies to a class
* containing an injectable constructor and governs how the injector reuses
* instances of the type. By default, if no scope annotation is present, the
* injector creates an instance (by injecting the type's constructor), uses
* the instance for one injection, and then forgets it. If a scope annotation
* is present, the injector may retain the instance for possible reuse in a
* later injection. If multiple threads can access a scoped instance, its
* implementation should be thread safe. The implementation of the scope
* itself is left up to the injector.
<p>In the following example, the scope annotation {#code #Singleton} ensures
* that we only have one Log instance:
*
* <pre>
* #Singleton
* class Log {
* void log(String message) { ... }
* }</pre>
You get the point right? whatever annotation you use or you create a custom one, and they inherit from #Scope it will ensure as singleton.

Related

How to implement a general class for singleton?

I've been trying to implement a state management project for my design patterns course. I have implemented the singleton because I know that's essential for keeping state of a class. What I would like to do is: Create a general class, so that others could use it in their projects. How do I do that? My code so far:
class StateManager{
static final StateManager _instance = StateManager._singleton();
StateManager._singleton();
factory StateManager(){
return _instance;
}
}
My other solution to try and make it general:
class AppProvider extends StateManager<AppProvider>{
int i = 10;
String data = "adas";
}
class StateManager<T extends AppProvider>{
static final StateManager _instance = StateManager._singleton();
StateManager._singleton();
factory StateManager(){
return _instance;
}
}
I want the AppProvider class to be the client class, and I want the StateManager to automatically handle the fact that AppProvider should be a singleton, and maintain the state of AppProvider.. I really don't know how to do that.
Forcing a class to be a singleton through inheritance alone is not going to work. That's not something that the language supports. Constructors are not inherited, neither are static members, and you need those to access the singleton.
In order to be able to create an instance of a class at all, the class needs a generative constructor.
That generative constructor will create a new instance every time it's invoked, because that's what generative constructors do.
For a subclass to be able to extend a class, the superclass must have an accessible generative constructor too, but at least the superclass can be made abstract.
In order to force a class to be a singleton (if you really want that, because a singleton is really something of an anti-pattern; it makes the class act like it's just a bunch of global variables, and that makes testing harder), each such class needs to have a public static way to access or create the instance, and a private generative constructor.
So, basically, your first approach does what is needed, and since the constructors are not inherited, you need to do that for every singleton class, and there is nothing useful to inherit.
So, there is nothing you can do with inheritance to make singleton-ness be inherited, and you can't even help because everything a singleton needs is static.
A different approach is to make the state classes entirely private, so you don't have to worry about someone else creating instances, and give them a constant generative constructor each, and then only refer to them using const _ThisState() or const _ThatState().
This puts the responsibility on the user (you!) to only create one instance of each state object, but it also gives a very easy way to do that, because const _ThisState() will provide the same instance every time.
Or use the enum pattern, and have:
abstract class State {
static const State thisState = const _ThisState();
static const State thatState = const _ThatState();
const State._();
void handle(Context context, Object argument);
}
class _ThisState implements State {
const _ThisState();
void handle(Context context, Object argument) { ... }
}
class _ThatState implements State {
const _ThatState();
void handle(Context context, Object argument) { ... }
}
and then just refer to the state instances as State.thisState. I find that more readable than creating instances of seemingly unrelated classes.

Inject annotation in base class - Dagger still wants to add injectable constructor

I'm using dagger.
Having the following classes:
class A {
#Inject
MyClass myClass;
}
class B extends A {
myClass.do();
}
When trying to compile this I'm getting
No injectable members on B . Do you want to add an injectable
constructor?
When moving myClass to B everything compiles. Any idea what might be the problem ?
Dagger can't know all subtypes of A so it doesn't know that it needs to generate adapters for classes like B.
Adding a no-arg constructor with #Inject will force the generation of code that can thus be used to perform injection on instances of B. You can also list B.class in the injects= list of a module to force adapter generation.

Ignore mocked object transitive dependencies

When a class implements an interface all we have to do is mock that interface.
However there are some cases when a class doesn't implement an interface, in that case binding the class to a mock leads guice to get the mocked object dependencies.
To clarify:
class A {
#Inject B;
}
class B{
#Inject C;
}
bind(a.class).toInstance(mock(B.class));
In this scenario, I don't care B's dependencies, but guice stills tries to inject C inside B.
Is there a way to avoid this without defining an interface?
First of all, I strongly recommend against using dependency injection in unit tests. When you're unit testing single class you should create it and pass its dependencies directly, through a constructor or methods. You won't have these problems then.
It's another story when you're writing integration tests though. There are several solutions to your problem.
Make sure all your classes receive dependencies only through injectable constructors. This way Guice won't inject anything because the object will be created by Mockito.
Use providers (and scoping, if needed). The following is equivalent to your attempt sans injection into B (I assume that you really meant bind(B.class).toInstance(mock(B.class)):
bind(B.class).toProvider(new Provider<B> {
#Override
public B get() {
return mock(B.class);
}
}).in(Singleton.class);
You should tweak the scope to satisfy your needs.
Using Mockito to partially solve this was quite easy.
You will need to use #Mock and #InjectMocks annotations like this
ATest{
#Mock B;
#InjectMocks A;
public void setUp(){
MockitoAnnotations.initMocks(this);
}
}
This way Mockito will do the inject instead of guice, there are a couple of restrictions to successfully inject the mock.
This works pretty well until your code have a strong dependency on a class.
Lets say inside A i have something like C obj = new C(); and C have injected fields.

Dependency Provision Precendence in Dagger

When you use an #Inject-annotated constructor to inform Dagger how to provide a dependency, can you later override it in a Module? Case: my production code uses a component with the annotated constructor, and I want to override it with a test implementation during testing. Would my override = true Module successfully override the production implementation during testing?
Or a more general questions, what takes precedence, Modules or annotated classes?
#Provides methods always trump #Inject Constructors and no-args Constructors (with field injection.
This is important, because an #Provides method is taking over responsibility for creation of the type, and that includes scoping, so a class marked #Singleton that is manually constructed in an #Provides method will not be scoped unless the #Provides method is scoped.
Note that you're using the word "override" in the context of testing... in this case, you don't need to use the #Module(override=true) setting (though there's no harm). It's just a precedence order, which resolves (in effect) as follows:
#Module(overrides=true) #Provides methods
#Module(overrides=false) (default) #Provides methods
Just In Time binding of #Inject constructors
Just In Time binding of no-arg constructors, IF class has #Inject fields.

Autofac: long-lived objects requiring short-lived objects during single method calls

I have a class X that I register in Autofac as single-instance because it's rather costly to create.
X has a method DoSomething that performs some action. However, to do its task in DoSomething, X needs additional dependencies. Typically, I'd inject them in the constructor, but in this case this gets difficult, because the dependency is bound to a narrower scope, e.g. instance-per-httprequest or instance-per-lifetime-scope. I can't use Func<T>, because this still resolves the objects in the lifetime in which the delegate is instantiated, so I don't gain anything.
The next option would have been to pass in the dependency as an argument to DoSomething, however the fact that there is a dependency is really just an implementation detail. In fact, I access X through an interface. I'd rather not cause a leaking abstraction by adding this parameter.
Resolving the dependency manually in the method (ie., service-locator style) isn't that great, either, of course. And even then I have the problem that I'm not sure how to access the proper IComponentContext. The class may be used in a web application or in a conventional application, or in a thread of a web application, but outside any request. How I do I determine the "current" lifetime scope?
So the basic problem is this:
class X : ISomething
{
public void DoSomething()
{
IDependency dependency = ?;
dependency.UseMe();
/* more stuff */
}
}
Ideally I'd like to be able to inject something into the constructor that will later allow me to resolve the actual object inside the current lifetime scope, like so:
class X : ISomething
{
IResolveLater<IDependency> dependencyResolver;
public X(IResolveLater<IDependency> dependencyResolver){
this.dependencyResolver = dependencyResolver;
}
public void DoSomething()
{
IDependency dependency = dependency.Resolve();
dependency.UseMe();
/* more stuff */
}
}
I'm certainly smelling design issues here, but I can't really put my finger on it. How can I solve this general problem: a long-lived object that requires locally-scoped, short-lived objects for single operations. I normally much prefer the different order: short-lived objects depending on long-lived objects.
I was also thinking about somehow moving the long-lived stuff out of X and create an additional, short-lived class XHelper that acts as some kind of "adapter":
class X
{
void DoSomething(IDependency dependency)
{
/* do something */
}
}
class XHelper : ISomething
{
X x;
public XHelper(X x, IDependency dependency)
{
this.x = x;
this.dependency = dependency;
}
public void DoSomething()
{
x.DoSomething(dependency);
}
}
Thus, when I need an ISomething, I'll resolve an XHelper (instead of an X) as needed which automatically gets the proper dependencies injected. It's a bit cumbersome that I need to introduce an additional type just for this.
How can I resolve this situation in the most elegant way?
It sounds to me like your use case is actually a simple factory pattern in disguise.
Create a simple DependencyFactory that has a Create() method that returns instances of whatever concrete class you want that implements IDependency, then have your DependencyFactory implement an interface IDependencyFactory.
Register the IDependencyFactory with the container, and modify the constructor of Class X to take an IDependencyFactory.
Use the IDependencyFactory instance to resolve a concrete instance of IDependency in your method DoSomething() and call DoSomething() on it.

Resources