I have this setup of component plus module, say FooComponent and FooModule, which provides a simple singleton, which needs to be replaced in one of the test variants. Therefore, in the variant I have instead FooTestComponent, which inherits FooComponent, but its #Modules annotation points to another module instead, FooTestModule. So far FooModule provides only one dependency, so no problem with that.
However, as dependencies that need not to be replaced in tests are added to FooModule, I see myself forced to replicate all of the methods to provide them in FooTestModule too since they can't be extracted to a parent abstract module that both FooModule and FooTestModule inherit from. What is the way to avoid this duplication?
The Dagger 2 User's Guide Testing Section contains advice for this very scenario.
To summarize the advice there:
Subclassing modules in order to swap in test doubles leads to the situation where you have to resolve all of the dependencies even if they are unused. Don't do this!
Instead of the approach in point 1, use different component configurations to achieve this: you can have a TestComponent that extends ProductionComponent and uses different modules that include bindings for test doubles
To achieve point 2, organize your modules for testability. This means considering modules as a collection of published and internal bindings and making sure you have a separate module for each published binding that has a 'reasonable alternative' i.e., an alternative you might like to replace with a test double that is not a mere internal dependency.
Alright well, so this is how it goes apparently: I'm really unsure this is the standard way of doing it, but deleting FooTestComponent and removing the annotations from FooTestModule allows FooTestModule to inherit from FooModule, and then you can instantiate FooTestModule where you override (but do not annotate) only the #Provides methods you need to mock.
Related
I just started getting into DI(dependency injection) frameworks and I was wondering should I inject every and any class or specific classes? How would I know which classes you should inject and which you shouldn't?
A lot of the tutorials(Dagger 2, Hilt, etc) that I've found don't seem to talk about this or don't explain it very well.
I don't have any code examples cause I'm trying out things as I read along with tutorials. Just trying to get a feeling of things.
Explain it as if I was 4 year old :)
My answer is no, you do not have to do that use dependency injection every time you need to create an object.
This is the intent of dependency injection according to Wikipedia
The intent behind dependency injection is to achieve separation of concerns of construction and use of objects. This can increase readability and code reuse.
So you should use dependency injection it would improve your code reuse and readability.
This article mentions some cases where you should use dependency injection to create objects
You need to inject configuration data into one or more components.
You need to inject the same dependency into multiple components.
You need to inject different implementations of the same dependency.
You need to inject the same implementation in different configurations.
You need some of the services provided by the container.
Imagine that you have username and password fields in an app that you would use to capture a user's detail, you do not have to use dependency injection to create a User object from the details, you can just create it directly, its not something that would be reused across your application, there are other object creation patterns that you should look into like factory pattern, abstract factory pattern, builder pattern e.t.c.
There's a certain number of classes which I always inject and never ask myself the question: the application context, shared preferences, DAOs, Retrofit, Json object. As you can see, these are usually related the third-party libraries or the Android framework.
Then there are classes which depend on those: the repository is a common example, but there are many more. For example you could have a preference manager which depends on shared preferences and context. Or you could have a class JsonExporter used to export user data which depends on DAOs and the Json mapper.
In turn, there are other classes which depend on those new classes: a view model/presenter in MVVM/MVP architecture could depend on both the repository and JsonExporter for example. At this point you have two choices:
Instantiate the class yourself. But that means you need to have access to all of the class' dependencies, which are only available through dependency injection...
so you might as well inject it. The cost of injection at this point is often very low, just adding #Inject to the constructor. Only the base dependencies have to be provided in a module.
From a certain number of injected base classes, the decision to inject those more nested in the dependency graph really comes automatically.
There are also cases where you'll have a class that depends on nothing. Perhaps you decided to extract code from a big class into another one. Or perhaps the class just has no dependencies. I probably wouldn't inject such a class, there's no point.
Singletons are often handy to inject because the dependency injection framework (e.g. Dagger) can make sure there's always only one instance automatically.
One reason why we do dependency injection is so that classes depend on abstractions, not concretions (aka inversion of control). It's useful to have your class depend on a Repository interface, because you can decide to provide it with the implementation you want, for example RealRepository in the app, and MockRepository in tests. Another example is flavors or build variants: an injected FlavorBehavior interface could have different implementations in two different flavors. It's not the class' responsability to decide which to use.
Note that this is not a definitive answer, and I'm not an expert on the subject. It's an opinion-based subject too.
I have been wondering what are the benefits of creating own #Component.Builder inside Components instead of using default ones?
The documentation does not say much about them, nor I could have found any reasonable examples. Anyone could share some thoughts?
A few of the advantages:
As Jeremy pointed out in the comments, you'll need an explicit interface if you want to use #BindsInstance.
An explicit interface lets you name your Module methods arbitrarily or add per-method Javadoc to your builder methods. This might be especially handy if your Module instances are optional or if they need to be manually created.
Some IDEs and tools don't do well with code-generated interfaces. An explicit Builder lets you define your own tool-readable interfaces and let Dagger generate the implementations later.
An explicit interface may make it easier to mock your component builders in unit tests. This may be especially handy for subcomponent builders, which observe the same rules as component builders.
I'm doing a small homemade project and I noticed that I wish to reuse a portion of code in other projects.
The conclusion is to move this code in a separate module and then publish it in my artifactory (I'm using maven) so it will become reusable.
The problem is that classes within my new module rely on each other. Usually, when I develop non-library project, I use Spring's inversion of control feature to resolve dependencies between the classes. But I can't use the dependency injection in my module, because the dependencies will be resolved only when bean is obtained from container.
Therefore, lets imagine the following situation:
I have Class1 in my module. It has field of type Class2, which should be.. lets say.. an instance of the same object always (i.e. singleton). My own ideas how to resolve it:
1) If Class2 doesn't contain any state, only methods (and plays an utility role) I can make it just static. Therefore I won't need to resolve this dependency, since I don't need to create it's instance anymore. But as a result, it can become really hard to test this type of class.
2) I can implement singleton pattern without using DI. The static Class2.getInstance() method could work, right?
3) I can forget about the idea of using singleton pattern and just create instance of Class2 with "new Class2()" expression (inline with field declaration or in Class1 constructor)
4) Somehow to use dependency injection so it could in a 'magic' way to inject my bean inside another one without using a container.
What is the best approach?
I would like to build my own custom DI framework based on Java annotations and I need a little direction to get started. I know it would be much easier to use one of the many wonderful frameworks out there such as guice or spring, but for the sake of my own curiosity, i'd like to build my own.
I'm not very familiar with annotations, so i'm having a bit of trouble finding resources and would really appreciate someone just sort of spelling out a few of the steps i'll need to take to get started.
As fore mentioned, id like to take a factory approach and somehow label my getters with an #Resource or #Injectable type annotation, and then in my business classes be able to set my variable dependencies with an #Inject annotation and have the resource automatically available.
Does anyone have any sort of resource they can pass along to help me understand the process of tagging methods based on annotations and then retrieving values from a separate class based on an annotation. A little direction is all I need, something to get me started. And of course i'll be happy to post a little code sample here once I get going, for the sake of others future reading of course.
EDIT
The resources I am using to put this together:
Java Reflection: Annotations
How to find annotations in a given package: Stack Overflow ?
Scanning Annotations at Runtime
I have not actually finished writing this yet, but the basic task list is going to be as follows (for anyone who might be interested in doing something similar in the future)
At class runtime scan for all #Inject fields and get object type.
Scan all classes (or just a specific package of classes (I haven't
decided yet)) for annotated methods #InjectableResource.
Loop all annotated methods and find the method that returns the
object type I am looking for.
Run the method and get the dependency.
It will also be helpful to note that when scanning all the classes I will be using a library called Javassist. Basically what this does is allows me to read the bytecode information of each class without actually loading the class. So I can read the annotation strings without creating serious memory problems.
Interesting that you want to build your own. I love Google Guice - it makes code so elegant and simple.
I've used this guide before which I found pretty useful for learning about annotations and how you can pull them out of classes and methods.
You will have to define your own Annotations which is done using #interface. Then you will have to define some kind of class for doing bindings e.g. where you see an interface bind in this concrete class. Finally, you will need some logic to pull it altogether e.g. go through each class, find each annotation, and then find a suitable binding.
Give consideration to things like lazy instantiation through Reflections and singletons. Guice, for example, allows you to use a singleton so your only using one instance of the concrete class, or you can bind a new version each time.
Good luck!
Have a look at the following methods:
java/lang/Class.html#getAnnotation(java.lang.Class)
java/lang/Class.html#getAnnotations()
java/lang/Class.html#getDeclaredAnnotations()
Methods of the same name also exist for the java/lang/reflect/Method, java/lang/reflect/Field and java/lang/reflect/Constructor classes.
So in order to use these sorts of methods, you need to know a bit about Java reflection.
I've seen it used, but I'm not sure the usage were good usecase examples. Do you have examples of idiomatic usages of Guice Mapbinder? (Cases where Mapbinder is really the correct tool to solve a problem)
Offhand, it looks like a reasonable way to create a registry of runtime-named implementations of a common interface. Consider selecting one of many plugins/modes/whatever from a command line or configuration file: the desired injection can't be known at compile time. A MapBinder provides an easy runtime lookup without resorting to type-switching.
I extensively use it in Guts-GUI.
You can take a look, in particular, at the ResourceModule, where it is used to map the right ResourceConverter<T> for a given type T:
Map<TypeLiteral<?>>, ResourceConverter<?>>
The MapBinder is directly created in the Resources helper class.
This way, any module can add its own resource converters for its own types, e.g. MessageModule adds its own converters.
I also used it as Map<Integer, WindowProcessor>> in WindowsModule to define an ordered list of WindowProcessors to be applied, one after another, to a newly created window..
Once again, this allows various modules to insert their own processor to the list applied to every window: ResourceModule uses it to add the ability of automatic injection of i18n resources to windows.