Hi I have a very simple dagger questions for android.
class Fooz {
#Inject Foo1 mFoo1;
public Fooz() {
....
}
}
class Fooz {
private Foo1 mFoo1;
#Inject public Fooz(Foo1 foo1) {
mFoo1 = foo1;
}
}
How are the two classes identical?
The first one injects Foo1 field directly while the second one assignes mFoo1 in the constructor.
For the second one, does Foo1 get injected from object graph as soon as Fooz is created and added to object graph?
If they are different, why so?
Thanks!
Constructor injection gives you more control over the object instantiation since using field injections means to restrict your class creation to reflection and rely on support to these particular injection annotations. Besides that, having the dependencies clearly on the constructor let the code easier to maintain and to test.
As far as I know, there is no difference regarding the way it is held on the dagger graph but a constructor call is always faster than injected fields.
In my opinion, we should use property only when we do not have control over the object creation, as in Activities and Fragments, per example.
These classes will behave the same when Fooz will be Injected using dependency injection. However they will behave differently when constructed using Constructor's you defined.
Example 1. Calling new Fooz() will result in mFoo1 being null.
Example 2. Calling new Fooz(foo1) will result in mFoo1 being initialized to foo1.
The preferred (personal opinion) way is to use dependency injection annotation on constructor, because it will avoid null pointer exceptions, as explained when comparing example 1 and example 2. What is more such constructor gives more flexibility when testing your classes as you can provide mocks, much easier.
These is sonarqube rule with better description, explaining what I mentioned https://sonarcloud.io/coding_rules?open=squid%3AS3306&rule_key=squid%3AS3306 .
Related
I'm a fairly experienced programmer but I'm fairly new to Guice and I'm not sure what the best practices are. Here is my possibly flawed understanding so far, please point out if I use incorrect terminology, question follows after:
Classes with a (public) no arguments constructor or an #Inject-annotated constructor (there may be only one such constructor) do not need to be explicitly bound/provided in the module. Though in the latter case, of course, the constructor parameters may need to be explicitly provided unless they can also be auto-provided by the same rule.
When instances of such classes are (automatically) provided, this can always be thought of as being done in injector.getInstance(...) fashion – #Inject-annotated members (like say injected private fields in the class, see my Car example) will also be injected and not left null.
The above two facts(?) partially solve the problem that one can not explicitly bind/provide an instance with #Inject-annotated members, since one can not create an instance inside a provider using injector.getInstance(...) and so the #Inject-annotated members will be left null.
The remaining problem case is when the constructor requires one or more parameters to be given during creation, the values of which cannot be known up front and therefore cannot be injected.
The solution generally seems to be to provide/inject a factory with a parameterized create method to create the instances when and as needed, but this could only be done using new, which does not work in general – what if the class contains #Inject-annotated members itself? Constructing the class with new will leave those should-be-injected members null-valued.
Here is sample code:
class Car {
#Inject
private Engine engine;
...
public Car(final String cannotBeInjected) {
...
}
}
How would I make Car (or a Car factory) injectable and still allow for an Engine instance to also be injected? A possible solution is to just assign the cannotBeInjected value via some setter after creation, but this just doesn't seem elegant.
If I follow dependency injection principle for a class design, I should make sure my class does not try to instantiate its dependencies within my class, but rather ask for the object through the constructor.
This way I am in control of the dependencies I provide for the class while unit-testing it. This I understand.
But what I am not sure is does this mean that a good class design which follows dependency injection principle means that its fields should never be initialized inline? Should we totally avoid inline initialization to produce testable code?
EDIT
Which is better 1 or 2?
1
public class Car {
private Tire tire = new Tire(); //
}
2
public class Car {
private Tire tire;
public Car(Tire tire) {
this.tire = tire
}
}
No, it surely doesn't mean inline initialization.
I'm not a Java user but this term is relevant to many programming languages.
Basically, instead of having your objects creating a dependency or asking a factory object to make one for them, you pass the needed dependencies into the object externally, and you make it somebody else's problem.
public SomeClass() {
myObject = Factory.getObject();
}
"Dependency Injection" is a 25-dollar term for a 5-cent concept. [...]
Dependency injection means giving an object its instance variables.
[...].
Dependency injection is basically providing the objects that an object needs (its dependencies) instead of having it construct them itself. It's a very useful technique for testing since it allows dependencies to be mocked or stubbed out.
Any application is composed of many objects that collaborate with each other to perform some useful stuff. Traditionally each object is responsible for obtaining its own references to the dependent objects (dependencies) it collaborates with. This leads to highly coupled classes and hard-to-test code.
A lot of reference from here
In my opinion, In general, if you think that the data field is a dependency, then let the dependency management container should manage it. What counts a dependency and what is not dependency is a tough question, and only you can decide.
For example: if your design of car allows working with different types of Tyres, then it's a dependency. Otherwise, inside a class Car you'll have to work with some kind of TyreFactory, which is not really reasonable.
If you work with DI container, testing the class will be a breeze. You'll have to provide a stub/mock to the class which is obviously a real benefit. So, in your example, if you go with the first solution then, how will you test that your car works with different types of Tyres?
I couldn't find any reasonable answer here on SO so I hope it's not a duplicate. So why should I prefer setter or constructor injection over simple
#Inject
MyBean bean;
I get the usage of the constructor injection if you need to do something with injected bean during your class initialization like
public void MyBean(#Inject OtherBean bean) {
doSomeInit(bean);
//I don't need to use #PostConstruct now
}
but still, it's almost the same like #PostConstruct method and I don't get setter injection at all, isn't it just a relic after Spring and other DI frameworks?
Constructor and property injection gives you the option to initialize the object even in a non CDI environment easily, e.g a unit test.
In a non-CDI environment you can still simply use the object by just passing the constructor arg.
OtherBean b = ....;
new MyBean(b);
If you just use field injection you usually must use reflection to access the field, because fields are usually private.
If you use property injection you can also write code in the setter. E.g. validation code or you clear internal caches that hold values which are derived from the property that the setter modifies. What you want to do depends on your implementation needs.
Setter vs constructor injection
In object-oriented programming an object must be in a valid state after construction and every method invocation changes the state to another valid state.
For setter injection this means that you might require a more complex state handling, because an object should be in a valid state after construction, even if the setter has not been invoked yet. Thus the object must be in a valid state even if the property is not set. E.g. by using a default value or a null object.
If you have a dependency between the object's existence and the property, the property should either be a constructor argument. This will also make the code more clean, because if you use a constructor parameter you document that the dependency is necessary.
So instead of writing a class like this
public class CustomerDaoImpl implements CustomerDao {
private DataSource dataSource;
public Customer findById(String id){
checkDataSource();
Connection con = dataSource.getConnection();
...
return customer;
}
private void checkDataSource(){
if(this.dataSource == null){
throw new IllegalStateException("dataSource is not set");
}
}
public void setDataSource(DataSource dataSource){
this.dataSource = dataSource;
}
}
you should either use constructor injection
public class CustomerDaoImpl implements CustomerDao {
private DataSource dataSource;
public CustomerDaoImpl(DataSource dataSource){
if(dataSource == null){
throw new IllegalArgumentException("Parameter dataSource must not be null");
}
this.dataSource = dataSource;
}
public Customer findById(String id) {
Customer customer = null;
// We can be sure that the dataSource is not null
Connection con = dataSource.getConnection();
...
return customer;
}
}
My conclusion
Use properties for every optional dependency.
Use constructor args for every mandatory dependency.
PS: My blog The difference between pojos and java beans explains my conclusion in more detail.
EDIT
Spring also suggests to use constructor injection as I found in the spring documentation, section Setter-based Dependency Injection.
The Spring team generally advocates constructor injection, as it lets you implement application components as immutable objects and ensures that required dependencies are not null. Furthermore, constructor-injected components are always returned to the client (calling) code in a fully initialized state. As a side note, a large number of constructor arguments is a bad code smell, implying that the class likely has too many responsibilities and should be refactored to better address proper separation of concerns.
Setter injection should primarily only be used for optional dependencies that can be assigned reasonable default values within the class. Otherwise, not-null checks must be performed everywhere the code uses the dependency. One benefit of setter injection is that setter methods make objects of that class amenable to reconfiguration or re-injection later. Management through JMX MBeans is therefore a compelling use case for setter injection.
Constructor injection is also a better way when you think about unit tests, because it is easier to call the constructor instead of setting private (#Autowired) fields.
When using CDI, there is no reason whatsoever to use constructor or setter injection. As noted in the question, you add a #PostConstruct method for what would otherwise be done in a constructor.
Others may say that you need to use Reflection to inject fields in unit tests, but that is not the case; mocking libraries and other testing tools do that for you.
Finally, constructor injection allows fields to be final, but this isn't really a disadvantage of #Inject-annotated fields (which can't be final). The presence of the annotation, combined with the absence of any code explicitly setting the field, should make it clear it is to be set by the container (or testing tool) only. In practice, no one will be re-assigning an injected field.
Constructor and setter injection made sense in the past, when developers usually had to manually instantiate and inject dependencies into a tested object. Nowadays, technology has evolved and field injection is a much better option.
Accepted answer is great, however it doesn't give credit to the main advantage of constructor injection - class immutability, which helps to achieve thread-safety, state safety, and better readability on the classes.
Consider you have class with dependencies and all of those dependencies are provided as constructor arguments, then you can know that the object will never exist in a state where dependencies are invalid. There is no need for setters for those dependencies (as long as they are private), so the object is instantiated to a full state or is not instantiated at all.
An immutable object is much more likely to well behave in an multithreaded application. Although the class still needs to be made internally thread-safe, you don't have to worry about external clients coordinating access to the object.
Of course this can be usefull only in certain scenarios. Setter injection is great for partial depencdency, where for example we have 3 properties in a class and 3 arg constructor and setters methods. In such case, if you want to pass information for only one property, it is possible by setter method only. Very useful for testing purposes.
I've seen a class declared with its only constructor being annotated with #Inject.
And I don't see the one constructor being called anywhere in the entire project.
So two questions:
<1> What does #Inject mean? (What does it do? Why is the constructor being annotated with it?)
<2> As mentioned, the constructor never gets called directly, does that have anything to do with the fact that it is annotated with #Inject?
Google Guice is a dependency injection library that allows you to construct objects simply by declaring relationships between them. Objects are constructed as they are demanded to construct other objects. You can also implement abstract classes or interfaces with different implementations by configuring Guice, which makes it very useful for running or testing your code.
#Inject annotates constructors and methods that determine what an object needs to be initialized. There are also a lot of other annotations that determine how Guice works. But simply annotating objects isn't enough; you also have to configure them with Guice bindings.
Here's a really simple example (from one of my applications). I have a MySQLDataTracker that requires a MysqlConnectionPoolDataSource:
public class MySQLDataTracker extends ExperimentDataTracker {
#Inject
public MySQLDataTracker(MysqlConnectionPoolDataSource ds) {
....
}
}
Note that MySQLDataTracker extends ExperimentDataTracker, an abstract class that can be implemented several ways. In my Guice bindings I declare that
bind(ExperimentDataTracker.class).to(MySQLDataTracker.class);
This declares that whenever I want an ExperimentDataTracker, a MySQLDataTracker will be constructed. I also need to make sure that the requisite object for constructing this is available, so I declare a provider:
#Provides #Singleton
MysqlConnectionPoolDataSource getMysqlCPDS() {
return (some thingy I construct...);
}
This says that there should only be a single connection pool data source. It also means that when I try to get an instance of ExperimentDataTracker, Guice has everything it needs to construct it. If I didn't have the above, it would throw an error.
ExperimentDataTracker tracker = injector.getInstance(ExperimentDataTracker.class);
However, it doesn't stop here. Other things depend on the ExperimentDataTracker, so it's used in turn to inject other objects. At the top level of my code there is actually only one call to getInstance, which makes Guice construct pretty much everything. I don't have to write the new statement anywhere.
I'm a big fan of Guice after seeing how it reduced the need for me to initialize a bunch of objects in order to initialize other objects. Basically I just ask for the object I want, and poof! it appears.
In Java, given the following class:
public class MyClass {
private final Dependency dependency;
public MyClass(Dependency dependency)
{
this.dependency = dependency;
}
public void doWork()
{
// validate dependency...
}
The doWork method needs to invoke a method that uses dependency.
Which of the following two variations is considered "best practice", and why?
// Access dependency directly
void validateDependency()
{
this.dependency.something();
}
// access dependency as passed to the method
void validateDependency(Dependency dependency)
{
dependency.something();
}
I find myself favouring the latter, passing the dependency directly to the method, as it makes the method easier to test in isolation (albeit, marginally).
However, I'm interested in the java convention / best practice here.
A class exists because you have state and operations that are coupled to that state. There's no good reason to pass part of that state as a parameter to a class method.
In fact, it would indicate to me that that piece of state should not actually belong to the class. Or that the method doesn't belong to the class.
Using a parameter "so that it's easier to unit test" is a good indication that the latter holds (the method should not be in the class).
Well, in your example you are asking the function to do something with Dependency which lends itself to a static function, not a member function.
My rule of thumb is: Use members directly when calling a method on an object that owns the member but pass references when doing/testing something directly related to the dependency and favor static methods for the latter
That a bit verbose but I hope it helps. As always try to "do the right thing" and differences this small won't likely make a huge impact on maintenance or readability of your code.
There isnt a right way to do it. I prefer just putting the variable there.
Dependency injection. The second option is "best".
If you make your "Dependency" class an interface it makes code more modular, easier to test, less coupled.