avaje-inject: Custom scope is ignored for Factory Beans

@Factory
public class AFactory {
  @Bean
  @ACustomScope
  Hello hello() {}

  @Bean
  @BCustomScope
  ExtendsHello extendsHello() {}
}

(where ExtendsHello extends Hello) Both are registered regardless whether any of the scopes are added as a module.

This leads to problems e.g. where you’d expect one binding of Hello, but instead there are two registered: Hello & ExtendsHello

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 15 (7 by maintainers)

Most upvoted comments

The class that needs converting is ConfigLoader. Currently ConfigLoader#load() is called in the CommonModule and is being casted to the proxy version (which has additional fields over the default backend server config) in the ProxyCommonModule, which is only loaded for proxy platforms. Given that multiple beans should have a different implementation depending on whether they’re a proxy platform, I thought that it’d be nice to have a @ServerScope and @ProxyScope.

One place where I’m already using it and I believe that it works is SimpleFloodgateApi which is the base implementation of FloodgateApi for server platforms. That class got the @ServerScope annotation. The proxy version of the FloodgateApi, ProxyFloodgateApi, extends SimpleFloodgateApi and gets the @ProxyScope annotation.

The ConfigLoader is a bit harder since it depends on a config loading library, and the returning class depends on whether it’s a proxy platform or not. Most classes depend on FloodgateConfig, but some proxy classes need ProxyFloodgateConfig. I wouldn’t have needed the scopes for this specific class if Avaje Inject looked at the class three of the returned instance, but Avaje Inject is compile time so that wouldn’t really work.

The idea I had was to make ConfigLoader a factory, something like:

@Factory
public final class ConfigLoader {
  @Bean
  @ServerScope
  FloodgateConfig serverConfig() {
    return load(FloodgateConfig.class);
  }
    
  @Bean
  @ProxyScope
  ProxyFloodgateConfig proxyConfig() {
    return load(ProxyFloodgateConfig.class);
  }

  // load method
}

This idea would result inproxyConfig binding to both ProxyFloodgateConfig and FloodgateConfig, and serverConfig only FloodgateConfig.

I can add

Awesome !!

the same Config profiles property name?

Well I was thinking that it might be better to use avaje.profiles / AVAJE_PROFILES for both avaje-inject and avaje-config. That would mean avaje-config might need to also support the existing config.profiles / CONFIG_PROFILES (and we could deprecate that at some future time).

What do you think?

Ok cool. Worth keeping open for a while and I’ll try to have a look at this. As I see it, if we can manage to support this without adding too much internal complexity then it would be worth it given that people will similarly try to do this going forward.