vipx / google-guice

Automatically exported from code.google.com/p/google-guice
Apache License 2.0
0 stars 0 forks source link

[RFE] add a bindCollection(Class component) to handle Component oriented programming #467

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
When using component oriented programming, it is usual to work with a 
collection of component instances, without any knowledge 
of their actual type. This is so close to guice that a very little effort could 
make it easy to mix both.

see attached an [http://sscce.org Short, Self Contained, Correct Example] to 
handle components with guice.

this code just requires the addition of a single method in the AbstractModule:

this "extra" method that this RFE is about, is for binding collection of 
components using the full power of guice for each 
particular instance.

here is the method

         /**
         * Bind Collection<C> to an instance that will contain every instances
         * that where binded to C.
         * 
         * @return a ScopedBindingBuilder to continue configuring the
         *         Collection<C> binding
         */
protected <C> ScopedBindingBuilder bindCollectionOf(final Class<C> 
componentType) {
            // build the type literal that matches Collection<C> sadly, java does not make it possible
            TypeLiteral<Collection<C>> collectionType = (TypeLiteral<Collection<C>>) 
TypeLiteral.get(Types.newParameterizedType(Collection.class, componentType));

            // creates a provider of the corresponding type
            Provider<Collection<C>> p = new Provider<Collection<C>>() {
                @Inject Injector injector;
                public Collection<C> get() {
                    Collection<C> collection = new ArrayList<C>();
                    for (Binding<C> b : injector.findBindingsByType(TypeLiteral.get(componentType)))
                        collection.add(b.getProvider().get());
                    return collection;
                }

            };
            // request that this class to be injected in order to get the injector
            requestInjection(p);
            // bind the collection type to this provider
            return bind(collectionType).toProvider(p);

        }

this code is mainly a wrap of findBindingsByType.

here is how component initialization looks like after

The configure method of my module can now be 
@Override protected void configure() {
            //A component implements I
            //B component implements I,J

            //My own component configuration ( 100% guicy) 
            bind(I.class).annotatedWith(Names.named("a")).to(A.class);
            bind(I.class).annotatedWith(Names.named("b")).to(B.class);
            bind(J.class).annotatedWith(Names.named("b")).to(B.class);

            // Simple guicy injection of components collection made possible by previous method
            bindCollectionOf(I.class).asEagerSingleton();
            bindCollectionOf(J.class);
        }

hope you'll like it.

Original issue reported on code.google.com by ericaro on 3 Feb 2010 at 4:23

Attachments:

GoogleCodeExporter commented 9 years ago
Consider using some form of Provider methods (
http://code.google.com/p/google-guice/wiki/ProvidesMethods ), or 
Multi/MapBinder (
http://code.google.com/p/google-guice/wiki/Multibindings ) to simplify this 
code and
provide what you're looking for.

Original comment by sberlin on 2 May 2010 at 12:24