Fredrik Wendt
Fredrik Wendt

Reputation: 1128

How do I wrap instances produced by Guice, while not creating them myself but have Guice inject dependencies as needed?

I want to use Guice to produce instances (actually singletons/single instances for the module/dependency injection context), but have some of the managed instances being wrapped in a proxy.

The idea behind this is to add a synchronization layer around a few items which deal with "one at a time" resources. The only solution I've come up with is to create two Injectors.

Given the code below,

public class ApplicationContext {
    private Injector injector;
    public <T> T get(Class<? extends T> cls) {
        return injector.getInstance(cls);
    }

    public ApplicationContext() {
        injector = Guice.createInjector(new Module() {
            binder.bind(InterfaceOne.class).to(ImplementationOne.class);
            binder.bind(InterfaceTwo.class).to(ImplementationTwo.class);
            binder.bind(InterfaceThree.class).to(ImplementationThree.class);
        });
    }
}

}

where ImplementationThree depends on InterfaceTwo, and ImplementationTwo in turn depends on InterfaceOne.

What I want now, is that after ImplementationTwo is instantiated, I want to wrap it in a Proxy before it's injected into ImplementationThree. So:

What I'd love to see, is a Guice interceptor that is invoked after the instantiation and injection of dependencies, but before it's handed over to the injector context.

I could use a Provider for ImplementationTwo, but then I don't know how to get an instance of InterfaceOne from Guice.

Upvotes: 1

Views: 1491

Answers (2)

Alen Vrečko
Alen Vrečko

Reputation: 886

Why not use plain old Guice AOP support? Something like

@SynchronizedAccess
public void foo(...){
    ...
}

this way you can see just by looking at the code that there is something more to the method.

If you absolutely want to wrap things in a Proxy:

If you only have a few classes to proxy, then @acerberus suggestions works fine.

To automate, you can use a #afterInjection, part of Custom Injections, and reassign the field to your proxy using reflection.

I find it a bit archaic to program using locks while we have things like akka around but YMMV.

Upvotes: 0

Arno Mittelbach
Arno Mittelbach

Reputation: 962

The Provider method can also use injection. Try

@Inject @Provides
public InterfaceTwo provideInterfaceTwo(InterfaceOne i){
    return InterfaceTwoImplementation
}

Upvotes: 3

Related Questions