I've been missing around one year in Android development and boy, what a large chunk to chew: Kotlin, LifeCycle, Room, ViewModel, Dagger and so on.
I am trying to get my head around the new MVVM recommended pattern and while it's really great to see something more "standardized" there are some things unclear.
To have things in a simple way, let's have a brief sample.
First, create the Entity
#Entity(tableName = "user_table")
public class User {
#PrimaryKey
#NonNull
#ColumnInfo(name = "name")
//vars, getters, setters
}
Then create the DAO
#Dao
public interface UserDao {
#Insert
void insert(User user);
...
}
Then, I need to make the Repository. This is basically where my questions start.
I see many examples, on official docs also using Dagger2. While I still struggle to fight with Dagger to proper understand dependency injection my question is, why do I need to use Dagger? I do understand that decoupling components allows easier testing, but is this necessarily for small projects? Why not interact between ViewModel, Repository, DAO directly without injection (maybe having classes passed on constructors)?
As a side note, probably it's a good point to start with Kotlin. While I find it pretty cool I see that many parts of the official docs/guides still only have Java samples... So I kind of want to learn the new stuff with old Java but in the same time, since my previous projects was on javascript, the switch to kotlin wouldn't be that hard...
Dependency injection has a lot of benefits. It promotes decoupling and testability as you already pointed out. But what's really attracting from dagger is the ease of dependency management. Dagger figures out your dependency graph at compile time, even provides mechanism to localize (or globalize) lifecycle and scope. It is component based as well so it can be easily architected.
Using dagger in small projects is arguable. If your project contains simple dependency graphs and is not an evolving one, the added code (and footprint) from dagger can be a little too much (not to mention the learning curve if you are not yet familiar).
But it is always a good thing to use dependency injection in my opinion. It promotes SOLID principle and cleaner architecture.
Related
I saw this question, but it was from the point of testability.
In my case, I see Dagger as an additional complexity for code (create #Provides methods, inject methods, remember all the right annotations). Should I still use Dagger if I just want to inject singletons like SharedPrefUtils? Is it really faster for this case?
Dagger was not made for creating Singletons and if creating a singleton is the reason you want to add Dagger to your project, then its an overkill. Dagger is a dependency injection framework that helps make the process of providing and injecting dependencies easier in a complex project. The #Singleton would help you ensure that only a single instance of a class is created when satisfying your dependencies it is not an alternative to the Kotlin object, they could even be used together. So like other answers and comments suggest if you have a small project and you could use simple design patterns like Singleton, Factory, and Abstract factory pattern.
Dagger is a dependency injection framework. For very simple applications, you can go with manual injection which will save you time because dagger can be difficult to set up and work with from the beginning. However, if you are planning on a production application which has a very long life span and will contain multiple UIs and multiple classes, then you are definitely going to need a dependency injection framework or strategy along the line.
There is an alternative for Kotlin which is Koin. Koin works more like a Service Locator and is easier to set up than Dagger but I will prefer dagger because it has survived the test of time.
It is up to you whether you want to use automatic dependency injection or manual injection so in the end you weigh your options and see what best fits your use case.
I am currently integrating architecture components into my app according to the official documentation and the sample apps provided by google (sunflower and todo-app). I realized that none of these use interfaces for ViewModels (the sunflower app does not even use interfaces for repositories).
My question is: is it reasonable to just omit the interfaces for ViewModels (including advantages and disadvantages)?
Is it reasonable to just omit the interfaces for ViewModels?
The below is quite general and applicable not just for ViewModels.
Advantages:
less code
Disadvantages:
won't be able to use most of the well-known design patterns;
won't be able to properly unit test classes (no mocking);
won't be able to properly use dependency injection frameworks;
code refactoring when using another concrete implementation.
The answer depends on the complexity of your ViewModel. If you are never going to create more than one implementation of an interface (including mocking), then there is no need to create the interface, so you can reduce the code and the overall maintenance burden.
That said the important things to consider are:
Can you unit test your view model, even without the interface (answer should be yes, otherwise you have some other problems IMO)
Can you still use a dependency injection framework (the answer is yes at least for some DI frameworks like Prism)
Are you only ever going to create one implementation of your ViewModel?
I believe that the mark of a well-designed ViewModel, should have a relatively simple implementation, and be easy to unit-test without having to resort to mocking.
I'm exploring the new Android Architecture Components and looking to implement it into an Android app. I am firmillair with MVVM as I use the paradigm on iOS development. Having read through the Android Architecture Components guide, provided by Google: https://developer.android.com/topic/libraries/architecture/guide.html
I have just a few questions...
In the above mentioned guide, Google use the UserRepository class that access these web service API - they go on to make this class a Singleton which is probably fine, if there were only ever one screen on the app that needed data from a REST API.
My concern, is this; it seems Google advocate the need to create a repository class on a per-ViewModel basis. This sounds very wrong to me, in having so many Singlton classes in the app. If we were to have 10 screens, with ten ViewModels - each needing its own Repository module - we then have ten singletons in our app. From an iOS dev perspective, this is wrong to have so many.
The solution to this, would be to have one mediator (Repository) class, that has public methods, exposing the API to get data from a REST API. The Web service part, would be in its own class. That way, we have a decent separation of concerns.
Is it best practice, to have one repository class, per, ViewModel - or to have one per app? I'm not 100% sure on this.
Lastly, I have the same concern when it comes to Room- is Google saying we create a DB on a per ViewModel bases or just one DB per app?
I don't think the architecture guide suggests to create a separate repository class for each ViewModel. In the example that is shown Google uses a library called Dagger to inject the singleton repository class into the ViewModel. It is normally best practice to split repositories (or managers) on functionality. UserRepository is responsible for all user related api calls for example.
If you turn this repository into a singleton that you can inject in any ViewModel, any ViewModel now has access to that specific repository.
After quickly looking into Room I found this little snippet (link):
Note: You should follow the singleton design pattern when instantiating an AppDatabase object, as each RoomDatabase instance is fairly expensive, and you rarely need access to multiple instances.
This to me means that you can implement the RoomDatabase much in the same way you can use your repository classes. Simply inject them as a singleton into your ViewModel so you don't need to have multiple instances of the same database.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I know this may be not the correct way to ask question but after reading lot and lot I am still confused about daggers and how it works and why we should use it. Since its been used in my current working project. Please somebody give me little hint in simple words what is the purpose of dagger will be very helpful.
Dagger is a compile-time JSR-330 dependency injection framework based on Java annotations.
What is dependency injection?
Dependency injection (sometimes termed Inversion of Control or IoC) is based on the idea that a given class should not need to know how to create or provide the classes it depends on. Providing those dependencies should be the responsibility of the class's user (or a separate class or factory).
For example, let's say you have class A that depends on class B, that depends on classes C and D. (In real terms, that might be an Application, that depends on a BusinessLogicClass, that depends on a Calculator and a Database.) It could look like this:
class A {
private B b = new B();
}
class B {
private C c = new C();
private D d = new D();
}
...but at that point it would be really hard to use a different C or D (calculator or database), even your B (business logic class) should work with a variety of data sources, or if you need to replace any of those pieces for unit testing. Dependency injection, as a concept, says that you should be able to pass in dependencies into the classes when you create them.
A a = new A(new B(new C(), new D())); // Now you get an A, but can replace any part of it.
What is a dependency injection framework?
A dependency injection framework automatically creates factories for all of your classes, so you can create an A without worrying about its dependencies, or its dependencies' dependencies.
A a = new AFactory().getA(); // Equivalent to the above, but easier!
Dependency injection frameworks usually come with a language for you to specify mappings, often called bindings, which is just a way of instructing that you should create a EImpl when a class asks for a EInterface or a FSubclass when a class asks for a FClass. This language also lets you choose when to create new instances: On every request, once across the whole app ("singleton"), or otherwise. Spring uses XML and Guice uses a custom Java class language for this; Dagger uses Java interfaces, classes, and annotations.
You can do dependency injection without a container or framework, but most of the time people think of a framework like Spring, Guice, or Dagger when you mention dependency injection. These frameworks automate away a lot of the new boilerplate you see above, which could otherwise make "manual" dependency injection hard to work with.
What about JSR 330?
Java standardized some interfaces and annotations as "JSR 330" to make it easier to switch between dependency injection frameworks, and to make it easy to write libraries that work in any framework. Like Spring and Guice, Dagger conforms to this standard.
Why is it a big deal that Dagger is compile-time?
Other dependency injection frameworks, including Spring and Guice, do their configuration at runtime: They use Java reflection to inspect classes' constructors, methods, and fields. This can be slow in production on servers and desktops, and is extremely slow on Android due to both VM differences and mobile processor/memory constraints. Consequently, teams at Square and Google wrote Dagger and Dagger 2 to use Java annotation processing to inspect the classes at compile time and automatically write standard Java code for plain Java objects to act like the factories above. Because this is plain Java without reflection, it can be much faster on Android and embedded systems, and can be optimized using existing tools.
Note, as well, that Dagger was written at Square by Bob Lee (who originally wrote Guice at Google); the Dagger 2 project is rewrite of Dagger maintained at Google that changes some of the specifics about how to configure Dagger and how to avoid using reflection. Both Dagger and Dagger 2 are annotation-based compile-time dependency injection frameworks for Java, but they're slightly different from one another.
What is dependency injection actually?
You will find a lot of technical contents about dependency injection but maximum time new learners find stuck to figure out the basic understanding of DI. Here is a real-life example of DI.
Importance of DI
Increase reusabilities of code
Good balance of loosely coupled dependancies
Ease to refactoring
Ease to test and debug
What is dagger?
Dagger is a DI framework that will generate a lot of boilerplate code for you to achieve the goal of dependency injection in Android development.
When to use dagger?
I got a clear vision of DI also with dagger from Android Dev Summit '19 session hopefully which will also clear your vision.
I am evaluating Dependency Injection (DI) frameworks for an Android app. The top contenders are: Dagger (with Butter Knife) and Android Annotations. I understand that Dagger and ButterKnife are from the same source- square and they complement each other. Here're are the key matrices that I am looking for:
Ease of use (our build is based on Gradle and we use Android Studio IDE)
Testing support (we use Robotium for functional testing and RoboLectric for unit testing)
Performance (DI frameworks use reflection, which one is faster?)
AndroidAnnotations
uses compile time annotation processing. It generates a sub class with an underscore apppended to the original name (MyActivity_ generated from MyActivity). So to have it work you always have to use the generated class for references instead of your original class.
It has a very rich feature set, see the list of available annotations.
Butterknife
uses also compile time annotation processing, but it generates finder classes which are used by a central class (ButterKnife). This means that you can use your original class for referencing, but you have to call the injection manually. A copy from the ButterKnife introduction:
#Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_activity);
ButterKnife.inject(this);
// TODO Use "injected" views...
}
The feature set is not so rich, ButterKnife supports view injection (AndroidAnnotations equivalent would be #ViewByIdand #ViewsById) and some event binding (for a complete list see the namespace directory here, just count the OnXXX event annotations).
Dagger
is a DI implementation for Android, similar to Guice. It also uses compile time annotation processing and generates object graphs which you use for manually injection. You distinguish between application object graph and scoped object graphs for injecting e.g. in activities. Here you see an Application.onCreate example:
#Override public void onCreate() {
super.onCreate();
objectGraph = ObjectGraph.create(getModules().toArray());
objectGraph.inject(this);
// use injected classes
}
I found it is harder to start with dagger, but this might be only my experience. However see some videos here for a better start: 1, 2
From the feature set point of view I would say that Dagger implements functionalities which could be compared to AndroidAnnotation's #EBean and #Bean functionality.
Summary
If you are comparing ease of use, testing support and performance I can't find much difference between using AndroidAnnotation and ButterKnife+Dagger. Differences are in the programming model (use classes with _ instead of using the original ones and call the injection manually) and in the feature set.
AndroidAnnotation gives you a full list of functionalities, but ties you to certain libraries. For example if you use it's rest api you have to use Spring Android. You also have annotations for features like OrmLite (#OrmLiteDao) regardless if you use OrmLite or not.
At the end it is a matter of taste, at least in my opinion.
Here is the Nice article in Dzone blog.
We to need to compare the features of each, such as :
Minimum Jars required
ActionBarSherlock compatibility
Injection for click listeners
POJO injection
Performance
Only Pojo Injection missing in butterknife! So looks like Butterknife is the winner!
Source
Google does ask specifically not to use dependency injection.
But by reading their request they seem to be referring more to the Guice and reflection based DI library's. Libraries such as android annotation use no reflection instead employing compile time generated code, while butterknife and dagger uses a small amount of reflection optimised for android but are supposedly slightly more powerful than android annotation. It really depends on the project and how much of a performance hit you are willing to take. In my opinion just using butterknife is sufficient to speed up code development by itself. If you need slightly more use android annotation and lastly if you are willing to take a slight performance hit due to reflection the best option without absolutely destroying performance with a powerhouse Guice based reflection use dagger + butterknife.
You should give a try at Toothpick.
Toothpick is (per the README):
pure java
fast, it doesn't use reflection but annotation processing
simple, flexible, extensible & powerful, robust & tested
thread safe
documented & Open Source
scope safe : it enforces leak free apps
test oriented : it makes tests easier
it works very well with Android or any other context based framework (such as web containers)
It can even be faster than Dagger 2 in most cases, and it's much simpler.
Note: Yes, I am one of the authors.
Use Android Annotations or Butterknife to ease your coding. But don't go for Roboguice! Roboguice forces your activies, fragments to extend to roboguice classes. Not fun, at all!
Dagger 2 is a much better option. You can use it along with Android Annotations if you'd like. I would just use Android Annotations for a simple app, but these days is good to work more with Dagger.
Seems like Google chooses dagger, as they are developing it jointly with Square, who created it.
Concerning Butterknife and Dagger themselves, there is the SO question difference-between-dagger-and-butterknife-android which clarifies how they complement each other.
The reddit-thread mentioned by #ChrLipp has someone who used all three on the same project, speaks highly of dagger+butterknife but also gives AndroidAnnotations its place:
For dependency injection, butterknife is used for Views, Dagger is
used for all objects and is highly recommended and Android Annotations
creates more of a framework for developing Android instead of
injecting objects into your classes so each library are quite
different from each other. Dagger is equivalent to Guice but is much
much faster. Dagger is more powerful then ButterKnife and Android
Annotations as it injects all objects rather than ButterKnife and
Android Annotations which only inject a certain set of objects.
Dagger can be a pain to setup and configure but is well worth it once
you have it done. But then again, because these are all quite
different from each other, it all depends on what your needs are for
the project.
Also, speaking of each one being quite different, in your project you
can use ButterKnife, Android Annotations and Dagger all in the same
project if you really want to. They each have the same idea but do
something different so you could use them all.
Eventually if you use one of the three, you'll have a hard time transitioning to Android's databinding. That's what's fastest if you need to consider performance:
https://developer.android.com/tools/data-binding/guide.html