pombreda / google-guice

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

Default Provider Binding #485

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
when we bind implementation class to customized provider,
we can't use default provider.
-----
sample cade ( can't use default provider)
-----
    // default provider key
    final Key<Hoge> originalKey = Key.get(Hoge.class, Names.named("_default"));
    Injector injector = Guice.createInjector(new AbstractModule() {
      @Override
      protected void configure() {
        // bind to default provider.
        bind(originalKey).toDefaultProvider(Hoge.class);
        bind(Hoge.class).toProvider(new HogeProvider());
      }
    });
    // get instance created by default provider!
    Hoge original = injector.getInstance(originalKey);
-----

I want to propose to add the feature of Default Provider Binding.It is what 
bind a type to default 
provider.

-----
  sample ( Default Provider Binding API image)
-----
    // default provider key
    final Key<Hoge> originalKey = Key.get(Hoge.class, Names.named("_default"));
    Injector injector = Guice.createInjector(new AbstractModule() {
      @Override
      protected void configure() {
        // want to bind to default provider
        bind(originalKey).to(Hoge.class);
        bind(Hoge.class).toProvider(new HogeProvider());
      }
    });
    // get instance created by HogeProvider
    // can't user default provider.
    Hoge original = injector.getInstance(originalKey);

-----

Original issue reported on code.google.com by k2.junio...@gmail.com on 23 May 2010 at 2:57

Attachments:

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
What is your use-case?

Original comment by sberlin on 23 May 2010 at 12:17

GoogleCodeExporter commented 9 years ago
Moved into issue 231, which I think is the problem you are referring to.

Original comment by sberlin on 23 May 2010 at 12:26

GoogleCodeExporter commented 9 years ago
I want to change a Guice configuration without recompiling. 
So I've been developing XML Configuration API for Guice.
(If you don't mind, please see http://code.google.com/p/guice-xml/)

To apply XML Configuration to a instance managed by Guice, 
I've needed PostConstruct event of the instance. I've implemented it by 
Provider. I've used Default Provider 
Binding in this case.

* coding image
{{{
class XmlConfigurationProvider<T> implements Provider<T> {
    Key<T> defaultProviderKey;
    Provider<Injector> injector;

    public ComponentInjectionListener(Key<T> defaultProviderKey,Provider<Injector> injector) {
        this.defaultProviderKey = defaultProviderKey;
        this.injector = injector;
    }

    @Override
    public T get() {
        // get a instance created by default provider.
        T t = injector.get().getInstance(defaultProviderKey);
        // apply xml configuration to a instance.
        injectValues(t);
        //call @PostConstruct method 
        postConstruct(t);
        return t;
    }
 ....
}}}

Original comment by k2.junio...@gmail.com on 23 May 2010 at 12:53

GoogleCodeExporter commented 9 years ago
Interesting... can't say I'm a fan of the XML configuration (I prefer the 
type-safety
of compilation), but to each his own.

You're probably better off using custom injections, described @
http://code.google.com/p/google-guice/wiki/CustomInjections.  Using the 
listener /
register methods there, you can call a @PostConstruct without having to wrap a 
provider.

Original comment by sberlin on 23 May 2010 at 2:46

GoogleCodeExporter commented 9 years ago
> Interesting... can't say I'm a fan of the XML configuration
> (I prefer the type-safety
> of compilation), but to each his own.

I agree. I'm not a fan of the XML configuration. But I must work with associate 
who can't understand Java.... 
They prefer XML configuration.

> You're probably better off using custom injections, described @
> http://code.google.com/p/google-guice/wiki/CustomInjections. Using the 
listener /
> register methods there, you can call a @PostConstruct 
>without having to wrap a provider.
Thanks for your advice.
I've tried to implement it by TypeLitener. But I've been able to implement it. 
Because I need to separate 
@PostConstruct method at each Key(TypeLiteral + BindingType) in XML 
Configuration. TypeLitener don't have 
the ability of it.

---------
  Problem Sample
    * same class
    * difference property.
---------
<beans>
  <bean class="example.SayHello" name="helloEN" 
        message="hello"/>

  <bean class="example.SayHello" name="helloJP"
        message="konnichiwa" />
</beans>
-----------------------------------

Original comment by k2.junio...@gmail.com on 23 May 2010 at 4:10

GoogleCodeExporter commented 9 years ago
In that example, those 'name="helloXX"' would work to let someone inject
@Named("helloXX")?  Localization may not be the best use for annotations (you
probably want to localize app (or scope) wide, as opposed to leaving it up to 
the
injectee to request a locale.  But, getting back to your initial request of "the
default provider" -- issue 231 shows how to solve that.

Create some internal annotation, say, @Default, and bind each class with both:
 bind(Foo.class).annotatedWith(Default.class).toConstructor((Constructor)InjectionPoint.forConstructorOf(Foo.class).getMember());
bind(Foo.class).toProvider(new Provider() {
  @Inject @Default Foo foo;
  public Foo get() { postConstruct(foo); return foo; }
});

The @Default toConstructorOf binding is the same as your "default provider".

Original comment by sberlin on 23 May 2010 at 6:17

GoogleCodeExporter commented 9 years ago
Indeed, this problem is solved by issue 231.
Thanks !

Original comment by k2.junio...@gmail.com on 23 May 2010 at 7:00