Is contructor overloading possible with dagger? - java

I have two data source class, LocalDataSource and RemoteDataSource. In DataRepository, I need both the classes but on need basis. I don't want to inject both the classes in DataRepository constructor. Instead want to overload constructor with single data source class. How to implement this with dagger?

To directly answer the question: Dagger supports one #Inject constructor at most. You can use a #Provides method to call any constructor or factory method you'd like, but if you want Dagger to manage your dependencies it will only read the single constructor you specify with #Inject. That said, that's not quite the right solution here in any case.
If your class needs a LocalDataSource or a RemoteDataSource, and you don't know which one until runtime, inject a Provider<LocalDataSource> and Provider<RemoteDataSource> (or Lazy<LocalDataSource> and Lazy<RemoteDataSource>). These objects are inexpensive Dagger-implemented abstractions over your LocalDataSource and RemoteDataSource constructors, which Dagger automatically allows you to inject: For any T available in your graph, you can inject Provider<T> and Lazy<T> (or even Provider<Lazy<T>>, as described in the documentation).
In this way, Provider and Lazy can help you avoid creating either DataSource instance until you know which one you need.
The difference between them is that Lazy<T> will locally cache the object instance, acting like a field in your class. Provider<T> will always consult your Dagger Component, which will in most cases will return you a newly-allocated object unless you've applied a scope like #Singleton. If your objects are expensive to construct, Lazy is a good choice, since you'll only request one instance across the lifetime of your consumer; if they are cheap to construct, then you might even choose to use a Provider within a method and letting your object be garbage-collected as soon as it is no longer needed.
Of course, as Steven and AlphaOne point out in the comments, you might also consider a design where your DataRepository consumer accepts an arbitrary DataSource that you or Dagger can provide. This generally makes sense, as DataSource is likely a useful interface and DataRepository might not need to know implementation details of the source it consults. However, if you need to handle an arbitrary source specification at runtime, at some point you'll still need to inject both a #Local DataRepository and #Remote DataRepository (assuming you've created #Qualifier annotations #Local and #Remote), and at that point it makes even more sense to use a Provider/Lazy instead of creating both DataRepository objects and their respective DataSources.

Related

Why default constructor written here, when we already have a parameterized constructor? [duplicate]

The no-argument constructor is a
requirement (tools like Hibernate use
reflection on this constructor to
instantiate objects).
I got this hand-wavy answer but could somebody explain further? Thanks
Hibernate, and code in general that creates objects via reflection use Class<T>.newInstance() to create a new instance of your classes. This method requires a public no-arg constructor to be able to instantiate the object. For most use cases, providing a no-arg constructor is not a problem.
There are hacks based on serialization that can work around not having a no-arg constructor, since serialization uses jvm magic to create objects without invoking the constructor. But this is not available across all VMs. For example, XStream can create instances of objects that don't have a public no-arg constructor, but only by running in a so-called "enhanced" mode which is available only on certain VMs. (See the link for details.) Hibernate's designers surely chose to maintain compatibility with all VMs and so avoids such tricks, and uses the officially supported reflection method Class<T>.newInstance() requiring a no-arg constructor.
Erm, sorry everyone, but Hibernate does not require that your classes must have a parameterless constructor. The JPA 2.0 specification requires it, and this is very lame on behalf of JPA. Other frameworks like JAXB also require it, which is also very lame on behalf of those frameworks.
(Actually, JAXB supposedly allows entity factories, but it insists on instantiating these factories by itself, requiring them to have a --guess what-- parameterless constructor, which in my book is exactly as good as not allowing factories; how lame is that!)
But Hibernate does not require such a thing.
Hibernate supports an interception mechanism, (see "Interceptor" in the documentation,) which allows you to instantiate your objects with whatever constructor parameters they need.
Basically, what you do is that when you setup hibernate you pass it an object implementing the org.hibernate.Interceptor interface, and hibernate will then be invoking the instantiate() method of that interface whenever it needs a new instance of an object of yours, so your implementation of that method can new your objects in whatever way you like.
I have done it in a project and it works like a charm. In this project I do things via JPA whenever possible, and I only use Hibernate features like the interceptor when I have no other option.
Hibernate seems to be somewhat insecure about it, as during startup it issues an info message for each of my entity classes, telling me INFO: HHH000182: No default (no-argument) constructor for class and class must be instantiated by Interceptor, but then later on I do instantiate them by interceptor, and it is happy with that.
To answer the "why" part of the question for tools other than Hibernate, the answer is "for absolutely no good reason", and this is proven by the existence of the hibernate interceptor. There are many tools out there that could have been supporting some similar mechanism for client object instantiation, but they don't, so they create the objects by themselves, so they have to require parameterless constructors. I am tempted to believe that this is happening because the creators of these tools think of themselves as ninja systems programmers who create frameworks full of magic to be used by ignorant application programmers, who (so they think) would never in their wildest dreams have a need for such advanced constructs as the... Factory Pattern. (Okay, I am tempted to think so. I don't actually think so. I am joking.)
Hibernate instantiates your objects. So it needs to be able to instantiate them. If there isn't a no-arg constructor, Hibernate won't know how to instantiate it, i.e. what argument to pass.
The hibernate documentation says:
4.1.1. Implement a no-argument constructor
All persistent classes must have a default constructor (which can be non-public) so that Hibernate can instantiate them using Constructor.newInstance(). It is recommended that you have a default constructor with at least package visibility for runtime proxy generation in Hibernate.
The hibernate is an ORM framework which supports field or property access strategy. However, it does not support constructor-based mapping - maybe what you would like ? - because of some issues like
1º What happens whether your class contains a lot of constructors
public class Person {
private String name;
private Integer age;
public Person(String name, Integer age) { ... }
public Person(String name) { ... }
public Person(Integer age) { ... }
}
As you can see, you deal with a issue of inconsistency because Hibernate cannot suppose which constructor should be called. For instance, suppose you need to retrieve a stored Person object
Person person = (Person) session.get(Person.class, <IDENTIFIER>);
Which constructor should Hibernate call to retrieve a Person object ? Can you see ?
2º And finally, by using reflection, Hibernate can instantiate a class through its no-arg constructor. So when you call
Person person = (Person) session.get(Person.class, <IDENTIFIER>);
Hibernate will instantiate your Person object as follows
Person.class.newInstance();
Which according to API documentation
The class is instantiated as if by a new expression with an empty argument list
Moral of the story
Person.class.newInstance();
is similar To
new Person();
Nothing else
Hibernate needs to create instances as result of your queries (via reflection), Hibernate relies on the no-arg constructor of entities for that, so you need to provide a no-arg constructor. What is not clear?
Actually, you can instantiate classes which have no 0-args constructor; you can get a list of a class' constructors, pick one and invoke it with bogus parameters.
While this is possible, and I guess it would work and wouldn't be problematic, you'll have to agree that is pretty weird.
Constructing objects the way Hibernate does (I believe it invokes the 0-arg constructor and then it probably modifies the instance's fields directly via Reflection. Perhaps it knows how to call setters) goes a little bit against how is an object supposed to be constructed in Java- invoke the constructor with the appropriate parameters so that the new object is the object you want. I believe that instantiating an object and then mutating it is somewhat "anti-Java" (or I would say, anti pure theoretical Java)- and definitely, if you do this via direct field manipulation, it goes encapsulation and all that fancy encapsulation stuff.
I think that the proper way to do this would be to define in the Hibernate mapping how an object should be instantiated from the info in the database row using the proper constructor... but this would be more complex- meaning both Hibernate would be even more complex, the mapping would be more complex... and all to be more "pure"; and I don't think this would have an advantage over the current approach (other than feeling good about doing things "the proper way").
Having said that, and seeing that the Hibernate approach is not very "clean", the obligation to have a 0-arg constructor is not strictly necessary, but I can understand somewhat the requirement, although I believe they did it on purely "proper way" grounds, when they strayed from the "proper way" (albeit for reasonable reasons) much before that.
It is much easier to create object with a parameterless constructor through reflection, and then fill its properties with data through reflection, than to try and match data to arbitrary parameters of a parameterized constructor, with changing names/naming conflicts, undefined logic inside constructor, parameter sets not matching properties of an object, et cetera.
Many ORMs and serializers require parameterless constructors, because paramterized constructors through reflection are very fragile, and parameterless constructors provide both stability to the application and control over the object behavior to the developer.
Hibernate uses proxies for lazy loading. If you do no define a constructor or make it private a few things may still work - the ones that do not depend on proxy mechanism. For example, loading the object (with no constructor) directly using query API.
But, if you use session.load method() you'll face InstantiationException from proxy generator lib due to non-availability of constructor.
This guy reported a similar situation:
http://kristian-domagala.blogspot.com/2008/10/proxy-instantiation-problem-from.html
Check out this section of the Java language spec that explains the difference between static and non-static inner classes: http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.1.3
A static inner class is conceptually no different than a regular general class declared in a .java file.
Since Hibernate needs to instantiate ProjectPK independantly of the Project instance, ProjectPK either needs to be a static inner class, or declared in it's own .java file.
reference org.hibernate.InstantiationException: No default constructor
In my case, I had to hide my no-arg constructor, but because Hibernate I couldn't do it. So I solved the problem in another way.
/**
* #deprecated (Hibernate's exclusive constructor)
*/
public ObjectConstructor (){ }
Summarizing of what is below. It matters if you want to be JPA compatible or strictly Hibernate
Just look at official documentation: https://docs.jboss.org/hibernate/orm/5.6/userguide/html_single/Hibernate_User_Guide.html#entity-pojo
Section 2.1 The Entity Class of the JPA 2.1 specification defines its requirements for an entity class. Applications that wish to remain portable across JPA providers should adhere to these requirements:
One point says:
The entity class must have a public or protected no-argument
constructor. It may define additional constructors as well.
However, hibernate is less strict in this:
Hibernate, however, is not as strict in its requirements. The differences from the list above include:
One point says:
The entity class must have a no-argument constructor, which may be
public, protected or package visibility. It may define additional
constructors as well.
More on that is right below:
https://docs.jboss.org/hibernate/orm/5.6/userguide/html_single/Hibernate_User_Guide.html#entity-pojo-constructor
JPA requires that this constructor be defined as public or protected. Hibernate, for the most part, does not care about the constructor visibility, as long as the system SecurityManager allows overriding the visibility setting. That said, the constructor should be defined with at least package visibility if you wish to leverage runtime proxy generation.

Static factories and dependency injection

In Effective Java (book), static factories are recommended.
On the other hand, keeping dependencies explicit, for example by using DI, is recommended.
But when I want to use a static factory, this explicitness will be skipped, because object instances will be received by calling the static factory method. With static factory methods, I won't have to pass in the object containing the static factory.
How can these two things go together?
Really good question.
Static factories have indeed this drawback (among others): they are not explicit and consequently they cannot be used as switchable dependencies.
I don't think that you can make the two things work together as a static method is associated to the class while the dependency injection is associated to instances.
So it is a choice of design.
Personally, I use the factory method as I don't want to allow to set explicitly the dependency returned by the factory.
It is the case as you want to master the objects creation : consistency, caching, and so for... and you want to provide a clear API.
It is a very straight way to guarantee that.
Setting an object with dependency injection will not provide that.
Generally, I did it for classes that I don't want neither to provide alternative implementations nor to mock during unit tests.
It is the case of business/model classes which I want to master the creation and also for some "utility" classes.
But as soon as the need to explicitly set the dependency happens, I refactor the static factory in something that allows to set the dependency explicitly.
If the master of the objects creation is always necessary, I transform the static factory into an instance factory that I inject.
Otherwise I inject directly the object that was returned by the factory.
There are two sides of the problem:
The object that is being created.
The object that is doing the
creating.
Factories, constructors, and auto-resolving containers are means of changing the way an object can be created (problem 2). That is entirely separate from how an object allows itself to be created (problem 1).
As a general heuristic:
Objects that are being created should be as flexible as possible in terms of how they can be constructed, and should explicitly advertise all their dependencies in their constructors (even if the constructors are made private and a factory is used by creators).
Creators should be as decoupled from the objects they created as your application needs to maintain its flexibility. Highly stable dependencies can be depended on directly. Dependencies that may change or be replaced should not
Differences between static factories, instance factories, constructors, and auto-resolution by container are largely just syntax. The biggest differences are semantic expression (what it communicates to a developer about the structure of the program) and the ability to resolve different implementations at runtime.
To answer your core question, the two things can go together because they are solutions to separate halves of the problem. You can use them both together.

DI with arguments in the constructor

So I'm implementing a Dependency Injection framework into my Java project (Google Guice) and everything is pretty good, I like it but there's a small problem;
I want to make a static instance of my main project's class (where it instantiates the dependencies, etc). But I don't know any method to instantiate it using Guice, I can't instantiate it manually because I'm using DI in the constructor of it (I have objects in the constructor) which means that I am not able to access the class' non-static variables needed to instantiate the class.
I tried using a Provider but I couldn't really understand where to bind it, because I don't want to have an interface for the main class (will if needed).
If you are wanting to mix a static instance of a class with dependency injection, you have somewhat missed the point of dependency injection: you can simply inject the instance of the class.
If you want there to be a single instance of a class for your injector, bind it in #Singleton scope: either:
bind(YourClass.class).in(Singleton.class);
in your module's configure() method, or
#Provides #Singleton YourClass provideYourClassInstance() {
// ...
}
in your module, or
#Singleton class YourClass {
// ...
}
in the actual class declaration.
Then just inject this instance like any other:
class SomeOtherClass {
#Inject SomeOtherClass(YourClass instance) {
// ... Do something with instance, like assign it to a field.
}
}
The point is that SomeOtherClass shouldn't need know anything about the lifetime of instance: it simply doesn't matter whether this is a singleton instance, or every class using it has its own instance.
You can get three different answers here depending on the question.
To directly answer the question in the title (DI with arguments in the constructor), you can mix DI with constuctor arguments by instead injecting a Factory. Though you're welcome to write one manually, Guice can do this for you as assisted injection (see FactoryModuleBuilder), or you can use the equivalent code-generated solution AutoFactory popular through Dagger.
If you're trying to initialize a static class's fields in a Guice application, Guice can do that for you as soon as the Injector is created. Simply call requestStaticInjection in a Module you feed to Guice. This, as Andy Turner pointed out, will cause you to miss out on some of the benefits of Guice: Because you're injecting the instance statically, there's very little opportunity for you to provide replacement implementations in tests or in other class reuse. Guice describes this more in the static injections section of its wiki:
When migrating an application from static factories to Guice, it is possible to change incrementally. Static injection is a helpful crutch here. It makes it possible for objects to partially participate in dependency injection, by gaining access to injected types without being injected themselves. [...]
Static members will not be injected at instance-injection time. This API is not recommended for general use because it suffers many of the same problems as static factories: it's clumsy to test, it makes dependencies opaque, and it relies on global state.
The best overall solution is in Andy's answer: Adapt your application to use DI, which will let it inject the objects that you would otherwise make static.

Java best way to share an object across other objects without using static

I have class A which instantiate class B which in turn do same for class C and so on, forming a large tree. I now need to instantiate an object that should be available all across the tree and I don't want to individually inject this object manually in all classes. I don't want to use a static because there could be different instances of class A running concurrently in different thread and this shared object must be unique per thread. I don't have much experience with thread safe operations.
Use Spring to manage the instance. That way you can inject your instance into any class that needs it and, provided the creation of the parent class is spring managed, the injected bean will be populated.
In some more detail, what you can do is define a class.
public class MyBean {
// Add your class details.
}
And ensure that Spring is either scanning its package or you have defined the bean in your applicationContext.xml file like this. The next stage is to inject this bean where you need to, using the #Autowired annotation..
#Autowired
private MyBean myBean;
And on the creation of that class, myBean will be populated with the same instance of MyBean that was initially created.
Advantages
Doing it this way means that your solution scales well. You can inject it anywhere without constantly changing constructors (and when you're creating more and more sub classes and relationships between classes, this is a prime candidate for Shotgun Surgery.
It's always good to learn about technologies that are used in industry.
Managing a single instance of a class using other methods (like the Singleton pattern) is usually a bad idea.
Disadvantages
Spring does a lot more than just inject objects, and you're pulling down a lot of classes to do just this, which will increase the size of your solution, although not significantly.
Extra Reading
Have a look at a basic Spring tutorial to get you going.
Have a look at the different scopes that you can create beans with, in case some of them suit your needs better.
You either need a local reference in the context that you want to use the object or you need a static reference. Since you don't want to use static you need to get a local reference. You can do this by passing the object in in the constructor or by adding a setter method. Then higher up the tree where ever you construct the child node you pass in the needed object.
You can have kind of a "Parallel Singleton" so to say, i.e. instead of having only one instance it will keep as many instances as there are threads, in a hashmap with a thread-related object being the key.

Clean Code: Dependency Injection forces procedural code, how to refactor

I have the below classes:
class Validator {
private final SchemaFetcher schemaFetcher;
#Inject
Validator(SchemaFetcher schemaFetcher) {...}
}
class DatabaseSchemaFetcher implements SchemaFetcher {
#Override
Schema loadSchema(final SchemaDefinition schemaDef);
#Override
boolean compareSchemaWithSource(final SchemaDefinition schemaDef, final Schema updatedSchema);
}
This is just one of the examples, I have some other classes like this which I inject into other classes as dependencies. But it makes my SchemaFetcher class like a singleton and I keep passing the schemaDefinition to every single method of it. This seems very procedural and I want to actually make SchemaDefinition an instance variable to the DatabaseSchemaFetcher class but in that case I would not be able to inject a SchemaFetcher Object into my Validator class and instead I should be doing
validate(String schemaName) {
SchemaDefinition schemaDef = buildSchemaDefinitionFrom(schemaName);
SchemaFetcher fetcher = new DatabaseSchemaFetcher(schemaDef);
}
But this makes me tightly coupled to the fetcher which is why I wanted to use Dependency Injection in the first place.
I can see that I could possibly have a default constructor for DatabaseSchemaFetcher and then a setSchemaDefintion() setter to acheive this but that violates the principle of building your object completely using the constructor.
How do I improve this to not have a procedural style fetcher but also inject my dependencies into the constructor? I prefer constructor injection because it clearly defines my dependencies without anyone looking into the implementation of the class to figure out the dependencies the class uses if I use a factory or service locator.
Dependency Injection is one of those very good ideas that seems so good that it gets badly overused. I would not inject the Fetcher into the Validator using the DI framework. Rather, I'd have the DI framework inject a factory into "main". The factory creates the Fetcher with the appropriate SchemaDefinition and passes it to the Validator.
Remember that we want a boundary separating "main" from the rest of the application, and all dependencies should point from "main" to the application. The application should not know about "main". i.e. "main" is a plugin to the application.
In general, DI should be used to inject into "main", and then main uses more traditional techniques to pass factories, strategies, or just regular old abstract interfaces into the application.
Why do you say you're tightly coupled to SchemaFetcher in your 2nd solution?
You're providing there an interface, so you're not coupled to any specific implementation, but only to the definition of what SchemaFetcher is (i.e - the contract of the SchemaFetcher)
You may consider to have a Validator class which takes into its CTOR the SchemaDefinition, and your DatabaseSchemaFetcher can hold a field to it. This way you will also be able to extend the Validator class change the validation logic if required.
But once again, the question of how to pass the schema definition object rises. Not sure injection should be used here - consider altering your design.
I'm not exactly sure what the use of Dependecy Injection and Procedural have to do with each other in this instance.
I think the real issue is that the way you've chosen to model you're objects does not reflect the stated goal.
In the code you've supplied Validator serves no purpose that I can see. If its purpose is to validate SchemaFetcher objects then it probably should have no state beyond the rules for validation then accept arbitary SchemaFetcher objects to validate.
As for DataBaseSchemaFetcher I once again struggle to understand what this does. If its stated purpose is only to fetch schemas then it requires no state in regards to DatabaseSchema objects and as such should accept DatabaseSchema for the methods in which it is charged with acting on a DatabaseSchema. Any internal state should only be related to the classes's fetching behavior.
One tried and true way to get past these painted in a corner situations is to sit down and try really hard to assign each class a single responsibility and keep in mind the following:
Thing really hard about the domain of the exact problem you are trying to solve.
Do not solve any problems you don't have.Take your dreams of extensibility and throw them away. They will almost always be wrong and will just be a huge time sink.
Accept that your design is necessarily deficient and you will have to change it later.

Categories