I want to achieve DYNAMIC dependency injection. Does GUICE support this? If not could you recommend any other DI framework?
The implementation that should be used for injection via #Inject must be determined during runtime e.g. via interaction with the user.
Similar to these questiones:
http://www.panz.in/2008/12/dynamic-dependency-injection.html
http://www.panz.in/2008/12/dynamic-dependency-injection.html
Thank you
The implementation needs to vary based on input, at some point you're going to have to resolve the input into some kind of class.
If you want that mapping to live in Guice, then you're basically getting an implementation based on a parameter, which maps to the SO question I just answered here. You can write a small injectable class that takes the input and returns a fully-injected implementation.
If you already have that mapping and have (for instance) a class literal in a variable, then you can just inject an Injector directly and ask it for the implementation.
class YourClass {
#Inject Injector injector;
SomeInterface yourMethod(String input) {
Class<? extends SomeInterface> clazz = getClassLiteralFromInput(input);
return injector.getInstance(clazz);
}
Class<? extends SomeInterface> getClassLiteralFromInput(String input) {
// Implement this as needed.
return SomeInstance.class;
}
}
Note that while you can always inject an Injector, you should only do so when you really don't know what kind of implementation you need (like here). In general you should inject the SomeInstance itself, or a Provider<SomeInstance> if you want to delay the creation.
We had similar requirement once, so what we did was use a factory pattern and add all the implementations in factory class implementation using spring.
That ways, when on run time we would know which implementation to use, we would make a call to my factory to provide implementation class.
Also, anytime you have more implementations you could update spring configuration for factory class.
This may not be close to design you have in mind, but this solved the purpose for us.
Cheers !!
Related
I have an issue with multiple implementations of interface, or rather with injecting them as a List.
This question is a direct follow up for question:
Java inject implementation using TypeLiteral
so I will refer havilly to those examples and refer to their solutions.
I have an interface:
public interface IImplementMe {
public String getValue();
}
and
I have multiple implementations of the IImplementMe interface from different modules of my project binded:
register(IImplementMe.class).annotatedWith(Names.named("someName")).to(SomeImplementation.class);
Everything zipped into list in module
private static class CustomTypeLiteral extends TypeLiteral<List<IImplementMe>> {
}
bind(new CustomTypeLiteral()).toRegistry();
And there are two assumptions (that makes this story different from linked question)
I do not know too much about implementations of IImplementMe, in particular if they are Singletons (I can force it if really needed)
They are binded in different modules not managed by me directly (and i don't want to bind those implementations myself)
Similarly, I want to inject a List of all of them in #Singleton class and call them whenever needed.
#Singleton
class SomeEndpoint {
#Inject
public SomeEndpoint(final List<IImplementMe> implementations){
///
}
}
And the question is: Is it guaranteed that Guice will pick up all implementations ? I know that they won't be available in constructor(the list will be empty) but after that the list should be refreshed as I understand Guice. I'm most concerned about scenario where implementations are not Singletons and they are not used anywhere else beside my class that injects List(SomeEndpoint in the example) (I'm worried that they'll never be initialized so never added to the list).
One additional thought: I'm not using Multibinder(I would like to avoid it if possible since I don't want to force other users to use it aswell, it will be a bit clearer if they could just register #Named implementation of IImplementMe it theirs modules).
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.
I'm new with Java Guice, and I have trouble with designing my application.
I'll try to explain my design and the desired result as simple as I can.
I have an interface called Ialgorithm, and 3 implementations of that interface, lets say IalgorithmA,IalgorithmB,IalgirthmC.
I have a class called myClass with the following constructor:
public myClass(Ialgorithm alg) {...}
Now I want to be able to inject an instance of one of the implementations of the Ialgorithm interface, using annotations:
I want at the end to be able to write in my main:
// ... intialize an Injector with a Moudle that extents AbstractModule
myClass a = injecotr.getInstance(key.get(myClass.class,Aannotation.class));
myClass b = injecotr.getInstance(key.get(myClass.class,Bannotation.class));
myClass c = injecotr.getInstance(key.get(myClass.class,Cannotation.class));
I read a few tutorials in the web, but I couldn't find exact way to achieve this.
In addition, and after the above issue will be solved, I extend my question:
Actually, The third implementation, IalgirthmC, is different from the two other implementations which contain a default constructor: its constructor is:
public IalgorithmC(Ialgorithm,int n) {...}
Now it becomes more complicated... because I want the Guice to inject the Ialgorithm parameter, but the int parameter shouldn't injected by the Guice (#Assisted), and this whole instance of IalgorithmC should be injected into myClass when using the Cannotaion.
Of course that I should provide a value for the int parameter and an annotation to the internal Ialgorithm in IalgorithmC.
Thank you all for any help.
This question talk about one solution for multiple implementations in guice.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is Inversion of Control?
I'm really confused with the concept of dependency injection.
I'm very new to software field and I have a doubt on the following scenario. Let say I need a Json parser class for my java code, So I'm adding the Json jar when executing the java program using the classpath argument. My program is dependent on Json jar, so that it mean I'm doing a dependency injection here?
An another example will be, using import statement does solve the problem of user class is depending on other class ( like Date in java ) so all these are the concept of dependency injection?
Where I'm making the concept.
Thanks in advance.
It's much more to do with how you link your components together. e.g. in the above, I would expect you to inject your parser into the class that needs it. e.g.
Instead of:
public class MyParserUsingClass {
...
public MyParserUsingClass() {
this.parser = new Parser();
}
}
you would do:
public class MyParserUsingClass {
...
public MyParserUsingClass(Parser injectedParser) {
this.parser = injectedParser;
}
}
Why do this ? Your class using the parser doesn't really care where the parser comes from and should really use an interface rather than a concrete instance. By injecting the parser, you can supply different instances depending on circumstances, mock it out for testing etc. Otherwise the class would just create it internally and you'd have no control over it. This is particularly key for configurable components, components that talk across the network, heavyweight components etc.
In your specific example, dependency injection would look like:
public class MyParser {
private final JsonParser parser;
public MyParser(JsonParser parser) {
this.parser = parser;
}
public Result parse(JsonInput input) {
Result = parser.parse(input);
}
}
Assuming that JsonParser is an interface, you can now provide any implementation of that interface to MyParser which does not depend on which specific implementation you choose to use.
Let's say you have a class the daes the job called MyCustomParser .
Now you want to allow to inject the parser in that class to obtain a different behavior against the type of Parser you will inject (the json could change,you would like to use another way to parse etc).
So you should create an Interface - IParser with a method called (by instance) ParseIt
Now you can have different implementation of this method depending on how you want to do the parsing.
All you need to do is to pass this Interface to the class that will use it MyCustomParser (you might do that passing it as parameter in the constructor).
In this case you are injecting the Parser in the MyCustomParser class
Dependency injection, in the strict sense, has nothing to do with importing classes or adding jar files to your classpath. It is meant to support the programming to interfaces principle and it's a form of Inversion of Control.
The main benefit it brings is that your code does not depend on explicit dependency implementation, but it uses abstractions instead. You depend on an interface and some instance of an implementing class for that interface will be "injected" in your class at runtime (either as a constructor parameter, some setter, or -- bad choice, in my opinion -- instance field).
As a consequence, you can for example change your persistence layer without touching the code in your service components, because your service classes only care about some DAO/Repository interfaces and you'll provide them with different implementations under the hood.
Dependency injection is more about reducing the instances where a class has to create instances of things it depends upon for itself.
Dependency injection aims to instead 'give' those dependencies to the consuming class via some external mechanism. Common methods include passing the dependencies in via the constructor, or setting them into a publicly 'settable' property of the class.
For example, dependency injection via the constructor could look something like this:
public class Parser
{
private IJsonParser parser;
public Parser(IJsonParser parser) {
this.parser = parser;
}
}
Which removes the need for the Parser class to do something like this:
public class Parser
{
private IJsonParser parser;
public Parser() {
this.parser = new JsonParser();
}
}
This follows from the principles of single responsibility - the Parser class doesn't need to be responsible for creating a JsonParser, nor should it care what specific JsonParser it uses - its concern is simply that it requires something that does the work specified by the IJsonParser interface, and leave it up to some higher controlling code to determine the appropriate concrete type that is best suited to doing that work.
I want to be able to call Interfaces in my class, but have spring instantiate them with the right implementation class behind the scenes.
I.e. Normally you can do:
IClass clz = new Class();
I want to have the line IClass clz; preferable in the middle of a method (or as one of the attributes if it can't be done), where clz is instantiated to the class I want by Spring.
The reason I'd like to do it this way is because I want to be able to be able to change which implementation I want to use simply by editing the context files.
Even better, would be knowing how to do the above with class contructors that expect parameters. i.e. new Class(ar1, arg2);
I hope this makes sense. Any help would be much appreciated.
You can make your class implement BeanFactoryAware and then Spring will inject the bean factory in your class. If you then want to get an instance of a class implementing your interface you say something like:
beanFactory.getBean(IClass.class);
If there are multiple beans that implement the same interface you will have to resolve by name. To create a new object each time you ask this, set the bean scope of the bean you're asking for to "prototype".
You can include code such as:
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
IClass clz = (IClass) context.getBean("beanName");
Not saying this is better per se than Gerco's answer btw, just it's an option, depending what you want to do.
You can also implement the ApplicationContextAware interface: I've found that using ApplicationContext gives me beans with filled-in properties, e.g. if you have an app.properties file which contains key/value property pairs which you expect to be resolved within the Spring config, beans retrieved via BeanFactory calls may not resolve those.
See this previous SO topic for more info.