Guice: Creating objects by methods - java

Suppose I have two similar (but different) methods (or maybe static methods) create_x() and create_y() to create objects (call them x and y) both (of class derived) of class Parser.
Now I want to bind the objects created by these two methods like as in answer to my previous question:
bind(Parser.class)
.annotatedWith(Names.named("x"))
.to(ParserXImplementation.class);
bind(Parser.class)
.annotatedWith(Names.named("y"))
.to(ParserYImplementation.class);
but with object created by create_x(), create_y() instead of instances of classes ParserXImplementation, ParserYImplementation. (So that there is no necessity to create classes ParserXImplementation, ParserYImplementation.)
Note that I want the objects to be singletons.
I want the answers both for the case if create_x(), create_y() are static methods and for the case if they are instance methods. If they are instance methods, the class containing them may itself be subject to dependency injection.
How to do this? (injecting dependencies to instances created by methods)

From https://github.com/google/guice/wiki/ProvidesMethods:
When you need code to create an object, use an #Provides method. The method must be defined within a module, and it must have an #Provides annotation. The method's return type is the bound type. Whenever the injector needs an instance of that type, it will invoke the method.
public class BillingModule extends AbstractModule {
#Override
protected void configure() {
...
}
#Provides
TransactionLog provideTransactionLog() {
DatabaseTransactionLog transactionLog = new DatabaseTransactionLog();
transactionLog.setJdbcUrl("jdbc:mysql://localhost/pizza");
transactionLog.setThreadPoolSize(30);
return transactionLog;
}
}
Further, it says that it can use annotation like #Named("x") and #Named("y") to differentiate x and y as described in the answer to Binding the same interface twice (Guice).
This is what I need (however the method is defined inside a module rather than in an arbitrary class).

Related

Java: How to get SubClasses in Provider in Dependency Injection

Given 3 classes: FooA, FooB and FooC, which are all subclasses of the abstract class Foo. However, all are using the same constructor with Dependency Injection, so I am using javax.inject.Provider to get fully injected instances of the subclasses.
Provider<FooA> fooAProvider
Provider<FooB> fooBProvider
Provider<FooC> fooCProvider
How can I sum the Providers up to become a Provider<Foo> fooProvider, while still being able to get instances of its subclass or is there another way to get rid of the multiple Provider?
You can combine a producer and qualifiers to distinguish resolved instances:
public class ProviderSuppliers {
#Producer
#Named("fooA")
public static Provider<Foo> getFooA() {
return //create Provider for FooA
}
#Producer
#Named("fooB")
public static Provider<Foo> getFooB() {
return //create Provider for FooB
}
#Producer
#Named("fooC")
public static Provider<Foo> getFooC() {
return //create Provider for FooC
}
}
Then you can inject them using the qualifier:
#Inject
#Named("fooA")
Provider<FooA> fooAProvider
#Inject
#Named("fooB")
Provider<FooB> fooBProvider
//and so on
Now, on Provider<Foo>: this is a little problematic because you technically can't do this:
Provider<Foo> fooA = new Provider<FooA>(); //you can't assign like this.
However, you can still declare as below and still get it to work by injecting the expected instance (the qualifier takes care of that)
#Inject
#Named("fooA")
Provider<Foo> fooAProvider
This is practically bad as you're simply going around type safety. The better approach would be to just have the same type declared on producer and at injection point, which also helps with type safety where Provider<FooX> objects are actually used.

Google Guice - Custom scope and assisted injection [duplicate]

I want to conduct a chain of processing elements and wire them together via Guice. Let's assume the following path:
interface A implemented by class AImpl needs some input
interface B implemented by class BImpl needs A
interface C implemented by class CImpl needs B
interface D implemented by class DImpl needs C
The dependency of A can only be resolved at runtime and not at configuration time. The usual approach would be to use Assisted Injection in this case to create a factory, that takes the missing instances as parameters, just like this:
public interface AFactory {
public A createA(String input);
}
But what I actually want is something like this:
public interface DFactory {
public D createD(String inputForA);
}
I don't want to manually pass AImpl-specific dependencies through the whole hierarchy.
Is it possible to achieve this with Guice? If not, what's the best way to circumvent this problem elegantly while still retaining benefits of injection?
Cheating way: Stick input in a static variable or singleton ThreadLocal. Set it before your pipeline starts and clear it after it ends. Bind everything else through DI.
Fancy way: In A, refer to a #PipelineInput String inputString but don't bind it in your main injector. Otherwise, bind dependencies as you normally would, including referring to #PipelineInput in other pipeline-related classes. When you do need a D, get it from your implementation of a DFactory, which I'm calling PipelineRunner.
public class PipelineRunner {
#Inject Injector injector; // rarely a good idea, but necessary here
public D createD(final String inputForA) {
Module module = new AbstractModule() {
#Override public void configure() {
bindConstant(inputForA).annotatedWith(PipelineInput.class);
}
};
return injector.createChildInjector(new PipelineModule(), module)
.getInstance(D.class);
}
}
Naturally, binding attempts for A, B, C, and D will fail outside of PipelineRunner for lack of a #PipelineInput String--you'll get a CreationException when you create the injector with those unsatisfied dependencies, as you discovered--but those pipeline-based dependencies should be easy to separate into a Module that you install into the child injector.
If this feels too hacky, remember that PrivateModules are also "implemented using parent injectors", and that the whole point of dependency injection is to make a dependency like inputForA available to the whole object graph in a decoupled way.
I see three options. They depend on how often you change the input for A .
1) Bind input as a constant in your module. This works only, if you know that value before you create the Injector and never want to change the value. See bindConstant
2) Use a private submodule which binds either A or the value for input inside that module. Basically you can have two or three instance graphs with different value. See newPrivateBinder.
3) Use a Scope ala RequestScope, SessionScope, ... This way you can change the input often but you must enter/leave the scope at some point to be defined. See Custom Scopes for an example.

How to annotate injector.getInstance?

I want to inject an instance from Guice injector in my unitTest.
Which diffrentiator can I use?
I know #annotation mechanism is used in ctor params
but junit doesn't allow ctor with params.
should I use class fields' #annotation?
public void setUp() throws Exception {
RoutingResponseRepository routingResponseRepository = injector.getInstance(RoutingResponseRepository.class);
}
e.g.
I want
#firstType RoutingResponseRepository
and
#secondType RoutingResponseRepository
For testing, you could just inject into your test-case-instance. Then you can use your injection-points just as you would in production code:
#Inject
#SecondType
private RoutingResponseRepository;
#Before
public void setUp() {
Guice.createInjector().injectMembers(this);
}
without caring about Types and Keys.
Use Injector.getInstance(Key):
injector.getInstance(Key.get(RoutingResponseRepository.class, firstType.class))
When referring to a binding, Guice internally uses an immutable Key instance, which refers to an annotation status (a binding annotation class, a binding annotation instance, or no binding annotation) combined with a type (a class literal, a Type instance, or a TypeLiteral). Matching this matrix, there are 9 different overloads of Key.get, which is the static factory method to get these Key objects. Overloads that take Class<?> are offered just for the sake of convenience.
In general, any time you want to represent a parameterized or annotated type (like in getInstance or bind), you can use an overload that takes a Key instead.

How to specify static method as annotation value in Java

I want to provide an annotation as the following:
public #interface CloneField
{
String sourceField();
Class<?> customCloner();
}
Where people can annotation fields on their classes and some framework will automatically copy fields to their classes instances by running a method from the customCloner on an external data source object.
For example:
class Test {
#CloneField(sourceField = "demoTest", customCloner = StringToIntCloner.class)
private int testField;
This will copy a string value from a field named demoTest on the external data source object into an int field on the user's object.
Since the customCloner doesn't hold any data I would want to define the cloning method as static without the need to instantiate it just for calling a method.
Usually I would define the custom cloner class as:
Class <? extends FieldCloner> customCloner;
where FieldCloner has a method for cloning.
But since static methods are not supported on interfaces there isn't a clean way to do so.
Is there an elegant way to do so in Java 7?
Beside the problem of running the method which can be solved by reflection I want to verify at compile time that the customCloner class has the appropriate method for cloning.

Force Singleton Pattern on a Class implementing an Interface

I better explain the question with an example.
I have an Interface Model which can be used to access data.
There can be different implementations of Model which can represent the data in various format say XMl , txt format etc. Model is not concerned with the formats.
Lets say one such implementation is myxmlModel.
Now i want to force myxmlModel and every other implementation of Model to follow Singleton Pattern.The usual way is to make myxmlModels constructor private and provide a static factory method to return an instance of myModel class.But the problem is interface cannot have static method definitions and a result i cannot enforce a particular Factory method definition on all implementation of Model. So one implementation may end with providing getObject() and other may have getNewModel()..
One work around is to allow package access to myxmlModel's constructor and create a Factory class which creates the myxmlModel object and cache it for further use.
I was wondering if there is a better way to achieve the same functionality .
Make a factory that returns
instances of your interface, Model.
Make all concrete implementations of the model package-private classes
in the same package as your factory.
If your model is to be a singleton, and you are using java
5+, use enum instead of traditional
singleton, as it is safer.
public enum MyXMLModel{
INSTANCE();
//rest of class
};
EDIT:
Another possibility is to create delegate classes that do all the work and then use an enum to provide all of the Model Options.
for instance:
class MyXMLModelDelegate implements Model {
public void foo() { /*does foo*/}
...
}
class MyJSONModelDelegate implements Model {
public void foo() { /*does foo*/ }
...
}
public enum Models {
XML(new MyXMLModelDelgate()),
JSON(new MyJSONModelDelegate());
private Model delegate;
public Models(Model delegate) { this.delegate=delegate; }
public void foo() { delegate.foo(); }
}
You can use reflection. Something like this:
public interface Model {
class Singleton {
public static Model instance(Class<? extends Model> modelClass) {
try {
return (Model)modelClass.getField("instance").get(null);
} catch (blah-blah) {
blah-blah
}
}
}
public class XmlModel implements Model {
private static final Model instance = new XmlModel();
private XmlModel() {
}
}
usage:
Model.Singleton.instance(XmlModel.class)
Actually, I don't like this code much :). First, it uses reflection - very slow, second - there are possibilities of runtime errors in case of wrong definitions of classes.
Can you refactor the interface to be an abstract class? This will allow you to force a particular factory method down to all implementing classes.
I used to ask myself the same question. And I proposed the same answer ;-)
Now I normally drop the "forcing" behavior, I rely on documentation.
I found no case where the Singleton aspect was so compelling that it needed to be enforced by all means.
It is just a "best-practice" for the project.
I usually use Spring to instanciate such an object,
and it is the Spring configuration that makes it a Singleton.
Safe, and so easy ... plus additionnal Spring advantages (such as Proxying, substituing a different object once to make some tests etc...)
This is more an answer to your comment/clarification to kts's answer. Is it so, that the real problem is not using the Singleton pattern but instead defining an eclipse (equinox) extension point schema that allows contributing a singleton?
I think, this can't be done, because everytime you call IConfigurationElement.createExecutableExtension you create a new instance. This is quite incompatible with your singleton requirement. And therefore you need the public default constructor so that everybody can create instances.
Unless you can change the extension point definition so that plugins contribute a ModelFactory rather than a model, like
public interface ModelFactory {
public Model getModelInstance();
}
So the extension user will instantiate a ModelFactory and use it to obtain the singleton.
If I guessed wrong, leave a comment and I delete the answer ;)

Categories