I am new to Guice. Is constructor injection preferred or field injection preferred?
Field injection appears to be quick and simple but testing would be a challenge as constructor is missing.
Thanks.
Use constructor injection
On their Minimize mutability wiki page, the Guice team says:
Minimize mutability
Wherever possible, use constructor injection to create immutable objects. Immutable objects are simple, shareable, and can be composed. Follow this pattern to define your injectable types:
[...]
Injecting methods and fields
Constructor injection has some limitations:
Injected constructors may not be optional.
It cannot be used unless objects are created by Guice. This is a dealbreaker for certain frameworks.
Subclasses must call super() with all dependencies. This makes constructor injection cumbersome, especially as the injected base class changes.
Method injection is most useful when you need to initialize an instance that is not constructed by Guice. Extensions like AssistedInject and Multibinder use method injection to initialize bound objects.
Field injection has the most compact syntax, so it shows up frequently on slides and in examples. It is neither encapsulated nor testable. Never inject final fields; the JVM doesn't guarantee that the injected value will be visible to all threads.
Would like to point out some differences so you can decide for yourself:
With constructor injection you can use the final modifier. Can't do that with field injection. Advantages of final members are off-topic and you can read up on that.
Writing test cases with constructor injection is easy (like you already mentioned)
With constructor injection all dependencies are mandatory. In order to declare a class you would need to know all its required dependencies.
With field injection, you will hide your dependencies for the class instead of making them explicit.
Above are just a few points to think about. I personally prefer Constructor Injection because of ease of testing and final support.
Both the types are fine. But you need to know when and where you need to use constructor injection.
Advantages of Constructor injection are,
It Provides Immutability (If used Properly)
In Constructor Injection you can use something like this.
public class MemberResource {
private final IMemberService memberService;
#Inject
public MemberResource(IMemberService memberService) {
this.memberService = memberService;
}
}
Unit testing becomes easier.
Advantage of Field injection is less coding.
Related
I have created Spring MVC application that has 3 user types. I've created separate controllers for each of them. Now in each of them, I have to inject service classes so I have done it like this:
#Controller
#RequestMapping("teacher")
public class TeacherController {
#Autowired
private StudentService studentService;
#Autowired
private GradeService gradeService;
#Autowired
private SubjectService subjectService;
#Autowired
private StudentGroupService studentGroupService;
#Autowired
private NewsService newsService;
#GetMapping("/index")
public String indexPage(Model theModel) {
List<News> tempNewsList = newsService.getNews();
theModel.addAttribute("theNewList", tempNewsList);
return "teacher/index";
}
This code is using field injection. Which is, as I now learned, a solution that should be avoided and replaced with constructor injection. So I've Autowired a constructor with all of these fields like this:
#Autowired
public TeacherController(StudentService studentService, GradeService gradeService, SubjectService subjectService, StudentGroupService studentGroupService, NewsService newsService) {
this.studentService = studentService;
this.gradeService = gradeService;
this.subjectService = subjectService;
this.studentGroupService = studentGroupService;
this.newsService = newsService;
}
Is this a good solution, creating such verbose constructor in such simple code? And what if I had even more services in my code? Is this even acceptable or in this case should I refactor my code, e.g. delegate services to other services or create more controllers?
You answered this well yourself! Spring addresses exactly this concern in the docs here in the box titled Constructor-based or setter-based DI?:
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.
That is, you should ideally refactor. Used SOLID principles and think "what is the one job of the class I'm creating?".
In conclution, according to the documentation if exist many DI you can evaluate every one and try to use set based and/or contructor based. The documentations eplain which one to use below:
Constructor-based or setter-based DI?
Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for mandatory dependencies and setter methods or configuration methods for optional dependencies. Note that use of the #Required annotation on a setter method can be used to make the property be a required dependency.
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.
Use the DI style that makes the most sense for a particular class. Sometimes, when dealing with third-party classes for which you do not have the source, the choice is made for you. For example, if a third-party class does not expose any setter methods, then constructor injection may be the only available form of DI.
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 .
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.
public class Widget {
#Inject
Fizz fizz;
public Widget(Fizz fizz) {
super();
setFizz(fizz);
}
public void setFizz(Fizz fizz) {
this.fizz = fizz;
}
}
Is this a Guice anti-pattern?!?!
If I say "fizz will be injected (via #Inject)", but then I allow a constructor and setter to accept a fizz, is this unnecessarily-redundant? Could it cause a conflict with Guice's injector?
I guess I'm confused as to:
When you should annotate a property with #Inject, vs.
When you should "inject" the property yourself via constructor/getter
Any thoughts? Thanks in advance!
Why not use something like this (i.e. use constructor injection) ?
public class Widget {
private Fizz fizz;
#Inject
public Widget(Fizz fizz) {
super();
this.fizz = fizz;
}
}
See also http://code.google.com/p/google-guice/wiki/Injections
You should use Constructor Injection for dependencies that are REQUIRED.
Use Property Injection when the dependency is OPTIONAL.
I would definitely say this is a problem, not because Guice can't do it, but because your code has a bug. Guice will try to invoke the default no-arg constructor (which doesn't exist) and fail.
But even if you added the no-arg constructor, this is still an anti-pattern. I've used DI frameworks for a while and never encountered a need to do field injection. I'm sure there's a use case for it, otherwise the Guice guys wouldn't have included it, but it makes your code impossible to test without special code, either bytecode manipulation or reflection.
Constructor injection is generally best for a number of reasons. It makes it clear to any caller exactly what your dependencies are, it allows you to initialze all your class's invariants at the same time (avoiding a partially-initialized class), and it's the only DI flavor that lets you create immutable objects, which are thread-safe and reduce program complexity.
My only use cases for method injection are when I don't want to require a subclass to declare the parent's dependencies, or when I want an "optional" dependency, but these are rare.