Simple answer:
* you bind Foo to FooImpl
* FooImpl is bound in RequestScope
- therefore, you can't inject FooImpl (or Foo) outside of Request Scope
* you inject Foo into DataServiceProvider
* you inject DataServiceProvider into ServiceImpl
* you bind Service to ServiceImpl
* you get an instance of Service outside of Scope
boom!
If you need an instance of Foo in DataServiceProvider, inject Provider<Foo>,
and don't call get() until you're in scope.
And traverse upwards as need be...
-Fred
On Tue, Feb 1, 2011 at 11:51 PM, Richard Maher <[email protected]> wrote:
> I have a service that takes a request scope object and a singleton. When I
> try to run the code below, I get the following error. How do I fix this?
>
> Exception in thread "main" com.google.inject.ProvisionException: Guice
> provision errors:
>
> 1) Error in custom provider, com.google.inject.OutOfScopeException: Cannot
> access
> Key[type=com.google.analytics.frontend.feed.impl.gami.GuiceTester$FooImpl,
> annotation=[none]] outside of a scoping block
> at
> com.google.analytics.frontend.feed.impl.gami.GuiceTester$FooImpl.class(GuiceTester.java:30)
> while locating
> com.google.analytics.frontend.feed.impl.gami.GuiceTester$FooImpl
> while locating
> com.google.analytics.frontend.feed.impl.gami.GuiceTester$Foo
> for field at
> com.google.analytics.frontend.feed.impl.gami.GuiceTester$DataServiceProvider.foo(GuiceTester.java:1)
> while locating
> com.google.analytics.frontend.feed.impl.gami.GuiceTester$DataServiceProvider
> for field at
> com.google.analytics.frontend.feed.impl.gami.GuiceTester$ServiceImpl.unscopedDataServiceProvider(GuiceTester.java:79)
> while locating
> com.google.analytics.frontend.feed.impl.gami.GuiceTester$ServiceImpl
> while locating
> com.google.analytics.frontend.feed.impl.gami.GuiceTester$Service
>
> 1 error
> at com.google.inject.internal.InjectorImpl$4.get(InjectorImpl.java:977)
> at
> com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1003)
> at
> com.google.analytics.frontend.feed.impl.gami.GuiceTester.main(GuiceTester.java:133)
> Caused by: com.google.inject.OutOfScopeException: Cannot access
> Key[type=com.google.analytics.frontend.feed.impl.gami.GuiceTester$FooImpl,
> annotation=[none]] outside of a scoping block
> at
> com.google.common.inject.SimpleScope.getScopedObjectMap(SimpleScope.java:110)
> at com.google.common.inject.SimpleScope.access$000(SimpleScope.java:48)
> at com.google.common.inject.SimpleScope$2.get(SimpleScope.java:94)
> at
> com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:40)
> at com.google.inject.internal.FactoryProxy.get(FactoryProxy.java:54)
> at
> com.google.inject.internal.SingleFieldInjector.inject(SingleFieldInjector.java:53)
> at
> com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:110)
> at
> com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:94)
> at
> com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254)
> at
> com.google.inject.internal.SingleFieldInjector.inject(SingleFieldInjector.java:53)
> at
> com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:110)
> at
> com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:94)
> at
> com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:254)
> at com.google.inject.internal.FactoryProxy.get(FactoryProxy.java:54)
> at com.google.inject.internal.InjectorImpl$4$1.call(InjectorImpl.java:968)
> at
> com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1014)
> at com.google.inject.internal.InjectorImpl$4.get(InjectorImpl.java:964)
> ... 2 more
>
> // Code:
>
> public class GuiceTester {
> public interface DataService {
>
> }
>
> public interface Foo {
> }
>
> @RequestScoped
> static class FooImpl implements Foo {
> }
>
> public interface Bar {
> }
>
> @Singleton
> static class BarImpl implements Bar {
> }
>
> static class DataServiceImpl implements DataService {
> private final Foo foo;
> private final Bar bar;
>
> @Inject
> DataServiceImpl(Foo foo, Bar bar) {
> this.foo = foo;
> this.bar = bar;
> }
>
> @Override
> public String toString() {
> return "MarsDataService [foo=" + foo + ", bar=" + bar + "]";
> }
> }
>
> public interface Service {
> Response process(Request request);
> }
>
> static class Request {
> private final Foo foo;
>
> Request(Foo foo) {
> this.foo = foo;
> }
>
> Foo getFoo() {
> return foo;
> }
> }
>
> static class Response {
>
> }
>
> static class ServiceImpl implements Service {
> @Inject @Named("serviceScope") SimpleScope scope;
> @Inject DataServiceProvider unscopedDataServiceProvider;
>
> @Override
> public Response process(Request request) {
> scope.enter();
> try {
> // explicitly seed some seed objects...
> scope.seed(Key.get(Foo.class), request.getFoo());
> Provider<DataService> dataServiceProvider =
> scope.scope(Key.get(DataService.class),
> unscopedDataServiceProvider);
> DataService dataService = dataServiceProvider.get();
> System.out.println("DataService: " + dataService);
> } finally {
> scope.exit();
> }
> return null;
> }
> }
>
> static class DataServiceProvider implements Provider<DataService> {
> @Inject private Foo foo; // this is request scoped and seeded
> @Inject private Bar bar; // this is a singleton
>
> @Override
> public DataService get() {
> return new DataServiceImpl(foo, bar);
> }
>
> }
>
> public static void main(String[] args) {
> Injector injector =
> Guice.createInjector(Stage.DEVELOPMENT, new AbstractModule() {
> @Override
> protected void configure() {
> bind(Service.class).to(ServiceImpl.class);
> bind(Foo.class).to(FooImpl.class);
> bind(Bar.class).to(BarImpl.class);
> bind(DataServiceProvider.class);
>
> SimpleScope serviceScope = new SimpleScope();
>
> // tell Guice about the scope
> bindScope(RequestScoped.class, serviceScope);
>
> // make our scope instance injectable
> bind(SimpleScope.class)
> .annotatedWith(Names.named("serviceScope"))
> .toInstance(serviceScope);
> }
> });
> Service service = injector.getInstance(Service.class);
> Request request = new Request(new FooImpl());
> service.process(request);
> }
> }
>
> // End code
>
> Thanks,
>
> Richard
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "google-guice" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected]<google-guice%[email protected]>
> .
> For more options, visit this group at
> http://groups.google.com/group/google-guice?hl=en.
>
--
You received this message because you are subscribed to the Google Groups
"google-guice" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-guice?hl=en.