I have a factory as below,
public final class Application {
private static IFoo foo;
public static IFoo getFoo(String bar)
{
// i need to inject bar to the constructor of Foo
// obvious i have to do something, not sure what
Injector injector = Guice.createInjector();
logger = injector.getInstance(Foo.class);
return logger;
}
}
This is the Foo definition:
class Foo
{
Foo(String bar)
{
}
}
OK. I m not sure how I can pass this parameter to Foo constructor with Guice?
Any ideas?
All the "Guice Constructor Parameter" answers seem to be incomplete in some way.
Here is a complete solution, including usage and a visual:
interface FooInterface {
String getFooName();
}
// Annotate the constructor and assisted parameters on the implementation class
class Foo implements FooInterface {
String bar;
#Inject
Foo(#Assisted String bar) {
this.bar = bar;
}
// return the final name
public String getFooName() {
return this.bar;
}
}
// Create a factory interface with a create() method that takes only the assisted parameters.
// FooFactory interface doesn't have an explicit implementation class (Guice Magic)
interface FooFactory {
Foo create(String bar);
}
// Bind that factory to a provider created by AssistedInject
class BinderModule implements Module {
public void configure(Binder binder) {
binder.install(new FactoryModuleBuilder()
.implement(FooInterface.class, Foo.class)
.build(FooFactory.class));
}
}
// Now use it:
class FooAction {
#Inject private FooFactory fooFactory;
public String doFoo() {
// Send bar details through the Factory, not the "injector"
Foo f = fooFactory.create("This foo is named bar. How lovely!");
return f.getFooName(); // "This foo is named bar. How lovely!"
}
}
Lots of helps here: https://google.github.io/guice/api-docs/latest/javadoc/index.html?com/google/inject/assistedinject/FactoryModuleBuilder.html
What you are probably looking for is to use a Guice factory. Particularly easy with the AssistedInject functionality, but they have a manual example at the top of the page. The short of it for the manual example is that you get the factory under non-static getFoo method that you pass whatever parameters to that you need and build the object from there.
This won't work directly if you have method interception in Foo, but it will work in many other cases.
To use AssistedInject, which to me has somewhat cleaner semantics and means less manual wiring, you'll need the guice-assistedinject extension in the classpath, then when creating Foo (well, FooImpl, we should be using interfaces):
#Inject
public FooImpl(#Assisted String bar)
{
this.baz = bar;
}
Then you create a FooFactory interface:
public interface FooFactory {
public Foo create(String bar);
}
Then in your guice module:
install(new FactoryModuleBuilder()
.implement(Foo.class, FooImpl.class)
.build(FooFactory.class));
You can check out the javadoc for FactoryModuleBuilder for examples with more complex factories.
I know that this is old thread but I just hit the issue myself today.
I only need two or maximum three different instances of 'Foo' and I really didn't want to write all the bolierplate code of Factory.
With a little googling I found this Stubbisms – Tony’s Weblog I would suggest this solution which is perfect if you know exactly what instances you need.
In Guice module:
bind(Foo.class).annotatedWith(Names.named("firstFoo")).toProvider(new Provider<Foo>() {
#Override
public Foo get() {
return new FooImpl("topic A");
}
});
bind(Foo.class).annotatedWith(Names.named("secondFoo")).toProvider(new Provider<Foo>() {
#Override
public Foo get() {
return new FooImpl("topic B");
}
});
Or in java 8:
bind(Foo.class).annotatedWith(Names.named("firstFoo")).toProvider(() -> new FooImpl("first"));
bind(Foo.class).annotatedWith(Names.named("secondFoo")).toProvider(() -> new FooImpl("second"));
And in constructor of your service where you need Foo instances:
#Inject
public MyService (
#Named("firstFoo") Foo firstFoo,
#Named("secondFoo") Foo secondFoo) {
}
And Foo in my case:
public class FooImpl implements Foo {
private String name;
public FooImpl(String name) {
this.name = name;
}
#Override
public String getName() {
return name;
}
}
Hope it helps someone.
If this class is a factory, it should be a Guice-managed object, having a non static getFoo method, and the getFoo method would just use
new Foo(bar)
Not every class needs to be instantiated by Guice.
Also see AssistedInject, to avoid creating this factory yourself and let Guice create one for you.
Although this isn't a direct answer to what you're asking, hope it helps. I was trying to understand where the constructor parameters are being passed earlier. If they are custom classes, they should be bind-ed in the module.
Class CustomHandler {
private Config config;
#Inject
CustomHandler(Config config) {
this.config = config;
}
public void handle() {
// handle using config here
}
}
Binding:
class Module extends AbstractModule {
bind(Handler.class).to(CustomHandler.class);
bind(Config.class).to(CustomConfig.class);
}
Injection:
CustomHandler handler = injector.getInstance(CustomHandler.class);
handler.handle();
Related
Toy example:
public class MyModule extends AbstractModule {
private static final Foo foo;
public MyModule(Foo foo) {
this.foo = foo;
}
#Override
public void configure() {
bind(Bar.class).toProvider(new Provider<Bar>() {
#Override public Bar get() {
return foo.getBar();
}
});
}
}
This lets me lazily invoke the .getBar() method of a user-provided Foo instance stored in a field of MyModule. However now the provider has its own dependencies - hence I need to define a non-anonymous class I specify an #Inject constructor on. Something like:
public class MyModule extends AbstractModule {
private static final Foo foo;
public MyModule(Foo foo) {
this.foo = foo;
}
#Override
public void configure() {
bind(Bar.class).toProvider(BarProvider.class);
}
BarProvider implements Provider<Bar> {
private Baz baz;
#Inject BarProvider(Baz baz) {
this.baz = baz;
}
#Override public Bar get() {
return foo.getBar(baz);
}
}
}
Perfect! Except Guice doesn't like this...
Exception in thread "main" com.google.inject.CreationException: Unable to create injector, see the following errors:
1) Injecting into inner classes is not supported. Please use a 'static' class (top-level or nested) instead of com.example.MyModule$BarProvider.
So, I'm in a bind. I need to access both a field on the module and an injected type from a Provider class at the same time. Is there any way to do this?
Note: this toy example excludes some of the actual complexity - in particular the bind() statement is more involved, which is why I can't simply define an #Provides method.
In part, injecting into an inner class is impossible because Guice can't reflectively create an inner instance without an outer parent instance (the equivalent of the arcane outerInstance.new InnerInstance() syntax).
Some options:
Make Foo injectable through your graph, possibly hidden in a PrivateModule so it's not exposed to your entire graph (if that's important to you).
Use an anonymous inner Provider (or an extracted equivalent), and get a Provider<Baz> from AbstractModule's getProvider(Class<T>) method. You'll get an exception if you try to call that before the Injector is created, but for creating a Provider the way you're doing, that's probably not a problem.
Post your bind outside of a toy problem, to see whether #Provides is possible with some cleverness.
Related: Accessing Guice injector in its Module?
I realize I was getting hung up on having Guice construct my Provider for me, which I don't actually need to do. Despite the example in Guice's documentation passing in a DatabaseTransactionLogProvider.class a better parallel to the first snippet would be to construct an instance of my Provider manually, and pass in both the Foo instance and a Provider<Baz> instance (provided by the module).
public class MyModule extends AbstractModule {
private static final Foo foo;
public MyModule(Foo foo) {
this.foo = foo;
}
#Override
public void configure() {
bind(Bar.class).toProvider(new BarProvider(foo, getProvider(Baz.class));
}
static BarProvider implements Provider<Bar> {
private final Foo foo;
private final Provider<Baz> bazProvider;
BarProvider(Foo foo, Provider<Baz> bazProvider) {
this.foo = foo;
this.bazProvider = bazProvider;
}
#Override public Bar get() {
return foo.getBar(bazProvider.get());
}
}
}
Let's say I have an interface Foo with method bar(String s). The only thing I want mocked is bar("test");.
I cannot do it with static partial mocking, because I only want the bar method mocked when "test" argument is being passed. I cannot do it with dynamic partial mocking, because this is an interface and I also do not want the implementation constructor mocked. I also cannot use interface mocking with MockUp, because I have no ability to inject mocked instance, it is created somewhere in code.
Is there something I am missing?
Foo foo = new MockUp<Foo>() {
#Mock
public bar(String s)(){
return "test";
}
}.getMockInstance();
foo.bar("") will now return "test"...
Indeed, for this situation you would need to dynamically mock the classes that implement the desired interface. But this combination (#Capturing + dynamic mocking) is not currently supported by JMockit.
That said, if the implementation class is known and accessible to test code, then it can be done with dynamic mocking alone, as the following example test shows:
public interface Foo {
int getValue();
String bar(String s);
}
static final class FooImpl implements Foo {
private final int value;
FooImpl(int value) { this.value = value; }
public int getValue() { return value; }
public String bar(String s) { return s; }
}
#Test
public void dynamicallyMockingAllInstancesOfAClass()
{
final Foo exampleOfFoo = new FooImpl(0);
new NonStrictExpectations(FooImpl.class) {{
exampleOfFoo.bar("test"); result = "aBcc";
}};
Foo newFoo = new FooImpl(123);
assertEquals(123, newFoo.getValue());
assertEquals("aBcc", newFoo.bar("test")); // mocked
assertEquals("real one", newFoo.bar("real one")); // not mocked
}
This is a simplified example of something I'm currently designing.
public class ExampleManager {
private Foo foo;
private ArrayList<Example> examples;
...
public ExampleManager() {
this.foo = new Foo();
this.examples = new ArrayList<Example>();
}
public void add(Example e) {
examples.add(e);
}
public void doSomethingWithExamples() {
for (int i = 0; i < examples.size(); i++) {
examples.get(i).doSomething();
}
}
...
}
public abstract class Example {
private Foo foo;
public Example(Foo foo) {
this.foo = foo;
}
...
}
In order to use the library, I have to extend the Example class and add examples to the ExampleManager, which should be the only class that modifies the Example objects.
So I have this Example1 class:
public class Example1 extends Example {
public Example1(Foo foo) {
super(foo);
}
...
}
and I currently initialize the manager like this:
ExampleManager manager = new ExampleManager();
Example1 example1 = new Example1(manager.getFoo());
manager.add(example1);
My Example needs the Foo object, but I'm wondering if I could get rid of the Foo argument in the Example1 constructor, so if someone uses the library, doesn't have to call manager.getFoo() in order to create an Example.
I'm thinking about the following solution, which will hide the Foo initialization, so the person who makes use of the library just have to implement the initialize(Foo) method, and the Foo would be initialized automatically when adding the example to the ExampleManager)
In ExampleManager: change the add(Example) method for:
public void add(Example e) {
e.initialize(foo);
examples.add(e);
}
In Example, initialize(Foo foo); would be an abstract method, so in Example1 I would have something like this:
#Override
public void initialize(Foo foo) {
this.foo = foo;
}
Is there any better way to do this?
It seems to me that you have some issues with your OO model in the first place if you need to hand objects around like you describe. - Or maybe your sample code does not reveal the real point of things.
Especially
ExampleManager [...] should be the only class that modifies the Foo objects
and
Example needs the Foo object
look somewhat 'special'.
Can you elaborate what the interactions are between the ExampleManager and the Foo instance, and between the Example and the Foo instance?
Ok, with regard to your comment, I propose the observer pattern, much like your initialize() approach:
public abstract class Example {
protected Foo callbackHandler;
public void setCallbackHandler( Foo handler ) {
this.callbackHandler = handler;
}
protected void doCallback( SomeType event ) {
if ( this.callbackHandler != null ) {
this.callbackHandler.doYourThing( event );
}
}
}
and have ExampleManager register itself or its Foo instance as the callback handler when an object is added to it. Non-abstract subclasses will then only need to call doCallback(...) whenever they want to communicate something and won't have to deal with any setup stuff for the callback.
I was looking to implement an interface on a package-private java class, but I am having some difficulty achieving this. Below is an example.
class Foo
{
String something(String str)
{
return ""str+"!";
}
}
public interface Bar
{
String something(String str);
}
What is the best approach here? My end goal is to implement the Bar interface on the Foo class. I am hoping to be able to cast Foo as Bar: (Bar)Foo
The Bar interface and the Foo class are in separate packages. Is there a way to do this?
Please advise.
You can't. The point of having the package level access it to precisely avoid seeing that class outside. What you can do however ( granted Foo is not final ) something like this:
C:\>type *.java
//Foo.java
package foo;
class Foo {
String something( String s ) {
return s + "!";
}
}
//Bar.java
package bar;
public interface Bar {
public String something( String s );
}
//Baz.java
package foo;
import bar.Bar;
public class Baz extends Foo implements Bar {
// make sure you're overriding
#Override
public String something ( String s ) {
return super.something( s );
}
}
//Use it: Main.java
package bar;
import foo.Baz;
class Main {
public static void main( String ... args ) {
Bar bar = new Baz();
System.out.println( bar.something("like this?"));
}
}
C:\>java bar.Main
like this?!
Da da!
The trick is to define the child in the same package as the parent so you can create a public version of it.
I hope this helps.
When you doesn't have control on a class but you want to make it look like an API that you have, then you Adapt it to fit your needs. Hint: Adapter Pattern
Foo needs to implement Bar
protected class Foo implements Bar
Also, I think Foo.something needs to be public in order to implement Bar.something
Side Note: While it was probably just as an example,
return ""str+"!";
should be:
return str + "!";
If Foo is package private, and you don't have access to the source, just the classfiles and/or the jar containing Foo.class, there's not much to do -- something that is package private is invisible to classes in the default package (where there is no package specified) and other packages.
You'll need to use inheritance or composition if you don't have access to the source code of Foo.
// By logically including your code in the package containing Foo,
// you can now access it. If Foo belongs to the default package, sorry.
// This also doesn't work if the package is sealed.
package where.foo.resides;
public interface Bar {
String something(String s);
}
// Inheritance
public class FooBar extends Foo implements Bar {
public String something(String s) {
return super.something(s);
}
}
// Composition
public class ComposedFooBar implements Bar {
private final Foo delegate;
public ComposedFooBar(Foo delegate) {
this.delegate = delegate;
}
public String something(String s) {
return delegate.something(s);
}
}
You can try using bytecode injection with BCEL or ASM and setting the interface at runtime. It's tricky, though.
There might also be a way to change interaces with reflection, but I doubt it.
Private is there for a reason.
What do I do with Guice when I need to call a parent constructor that is also injectable? e.g. I have an abstract parent class that has a constructor that is injected with an object shared by all derived children and each child also has an injectable constructor.
Calling super() wont work because Java wants me to pass in the object as a paremeter rather than have Guice inject.
Thanks
EDIT: I am wondering if maybe I need to use method injection instead?
You'd need to do the exact same thing you do if you weren't using Guice... declare any parameters the parent constructor requires as parameters to each child's constructor as well, and pass those to super.
So if your abstract parent class's constructor takes a Foo, a child class's constructor needs to look like:
#Inject public ChildClass(Foo foo, Bar bar) {
super(foo);
this.bar = bar;
...
}
Buried in the Minimize Mutability section of the Guice Best Practices, you'll find this guideline:
Subclasses must call super() with all dependencies. This makes
constructor injection cumbersome, especially as the injected base
class changes.
In practice, here's how to do it using constructor injection:
public class TestInheritanceBinding {
static class Book {
final String title;
#Inject Book(#Named("GeneralTitle") String title) {
this.title = title;
}
}
static class ChildrensBook extends Book {
#Inject ChildrensBook(#Named("ChildrensTitle") String title) {
super(title);
}
}
static class ScienceBook extends Book {
#Inject ScienceBook(#Named("ScienceTitle") String title) {
super(title);
}
}
#Test
public void bindingWorked() {
Injector injector = Guice.createInjector(new AbstractModule() {
#Override protected void configure() {
bind(String.class).
annotatedWith(Names.named("GeneralTitle")).
toInstance("To Kill a Mockingbird");
bind(String.class).
annotatedWith(Names.named("ChildrensTitle")).
toInstance("Alice in Wonderland");
bind(String.class).
annotatedWith(Names.named("ScienceTitle")).
toInstance("On the Origin of Species");
}
});
Book generalBook = injector.getInstance(Book.class);
assertEquals("To Kill a Mockingbird", generalBook.title);
ChildrensBook childrensBook = injector.getInstance(ChildrensBook.class);
assertEquals("Alice in Wonderland", childrensBook.title);
ScienceBook scienceBook = injector.getInstance(ScienceBook.class);
assertEquals("On the Origin of Species", scienceBook.title);
}
}
A better alternative is to use something similar to the strategy pattern to encapsulate all the fields the superclass wants to inject, and then the subclass can inject that. For example:
public abstract class Animal {
/**
* All injectable fields of the Animal class, collected together
* for convenience.
*/
protected static final class AnimalFields {
#Inject private Foo foo;
#Inject private Bar bar;
}
private final AnimalFields fields;
/** Protected constructor, invoked by subclasses. */
protected Animal(AnimalFields fields) {
this.fields = fields;
}
public Foo getFoo() {
// Within Animal, we just use fields of the AnimalFields class directly
// rather than having those fields as local fields of Animal.
return fields.foo;
}
public Bar getBar() {
return fields.bar;
}
}
public final class Cat extends Animal {
private final Whiskers whiskers;
// Cat's constructor needs to inject AnimalFields to pass to its superclass,
// but it can also inject whatever additional things it needs.
#Inject
Cat(AnimalFields fields, Whiskers whiskers) {
super(fields);
this.whiskers = whiskers;
}
...
}