2009/4/4 Bob Lee <[email protected]>:
> On Fri, Apr 3, 2009 at 11:57 PM, Dhanji R. Prasanna <[email protected]>
> wrote:
>>
>> If we add a method to Scope it will break a lot of existing code out there
>> that doesn't implement that method. Not to mention binaries that are
>> compiled against the current version of Scope.
>
> I think James means that a scope may or may not implement Iterable, i.e.
> he'd do an "instanceof Iterable" at run time.
>
> I'd just assume keep scopes simple though. I'm not a fan of
> PostConstruct/PreDestroy in general.

OK how's this for another idea - one that keeps the scopes nice and
simple, doesn't require hacking the InjectionListener API - or indeed
the public guice API at all, but just requires an optional minor
refactor in each Scope to implement (and a few trivial delegation
methods here and there - more on that later...).

So a Scope by definition of its interface is just a proxy Provider
which takes the Key and the real provider, looks up some cached value
and if its not set, lazily creates it from the real provider. e.g.
something like this..

    public <T> Provider<T> scope(Key<T> key, final Provider<T> creator) {
      return new Provider<T>() {
        public T get() {
          T t = getCachedValue(key);
            if (t == null) {
              t = creator.get();
              setCachedValue(key, t);
            }
            return t;
          }
        }
    }


This is how singleton/request/session scopes all work and I'm sure
pretty much all scopes are like this.

Now from an Injector we can get the Bindings which expose the
Provider. So we already have an easy way to iterate through all the
bindings/scopes - it'd be trivial to filter out all the bindings for a
certain scope or whatever etc.

The only thing that is missing is that from a provider is the ability
to expose the getScopeValue(). i.e. if we introduced an internal
interface (none of this has to be part of the public Guice API/SPI as
its only a couple of tooling methods & frameworks that are gonna use
it) called CachingProvider

/** A scope may implement this interface so it can expose its cached value */
interface CachingProvider<T> extends Provider<T> {
 /** Returns the cached value for the given key or null if its not
cached or supported */
 T getCachedValue(Key<T> key);
}

then a very minor and optional refactor in scopes would look like this...

    public <T> Provider<T> scope(Key<T> key, final Provider<T> creator) {
      return new CachingProvider<T>() {
        public T get() {
          T t = getCachedValue(key);
            if (t == null) {
              t = creator.get();
              setCachedValue(key, t);
            }
            return t;
          }
        }
       public T getCachedValue(Key<T> key) {
          ...
       }
    }

So no new iteration required on the scopes; we purely have an optional
interface on the providers the scopes create.

The only issue remaining now is that this provider gets wrapped a few
times before its put into the binding; so we'd need to add a few
delegates of CachingProvider on the proxies & facades that are invoked
before the scope's provider is. Then anyone who knows this trick could
iterate through all the objects in a scope if they want - or folks
could implement their own close/pre-destroy hooks above Guice - while
keeping the core of Guice nice and clean and Bob doesn't have to ever
see a pre-destroy hook :).

I've created a patch for this to show how trivial it is which works
for singleton/request/session with very minimal changes to those
scopes...
http://code.google.com/p/google-guice/issues/detail?id=354

Thoughts?

-- 
James
-------
http://macstrac.blogspot.com/

Open Source Integration
http://fusesource.com/

--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to