How widely-used do you foresee generic-typed services/healthchecks being?
As long as the limitation is clearly documented... If most services could use @Service annotation, but we still let a generic-typed Service register itself a slightly-more-messy way, that seems like an OK compromise to me. Although... that does make the tiny dev on my shoulder cry a little from having two solutions to the same problem.
Rather than eager singletons to instantiate services when the injector is created, and scanning the entire classpath... Could the GWizard application's configuration be what drives service creation?
For example, in my dropwizard/guice project... I configure a list of plugins in my YaML:
plugins:
- type: alerts
- type: history
- type: auth-shiro
Dropwizard creates its configuration POJO using its Discoverable interface to do the Jackson polymorphic deserialization. When my guice-injector-bundle's run() method is called w/ the configuration POJO,
it scans for Guice Module's annotated with that plugin name, and adds them to the injector:
Set<String> overrideModules = Sets.newHashSet();
for (PluginConfigurationFactory cfg : configuration.getPlugins()) {
final JsonTypeName ann = cfg.getClass().getAnnotation(JsonTypeName.class);
overrideModules.add(ann.value());
}
// ... uses reflection to find all the guice modules in the set of names and build a compound module
in a main application module, we bind a 'plugin loader' eager singleton, which has a method like:
@Inject
public void loadPlugins(Injector injector,
DwApplicationConfiguration cfg) {
for (PluginConfigurationFactory pluginCfg: cfg.getPlugins()) {
try {
logger.debug("Loading plugin cfg: {}", pluginCfg);
pluginCfg.load(injector);
} catch (Exception ex) {
final JsonTypeName ann = pluginCfg.getClass().getAnnotation(JsonTypeName.class);
logger.error("failed to load plugin '{}'", ann.value(), ex);
}
}
}
and each pluginConfig's load() method took the injector and did whatever instantiation it required. That works for the way we slapped Guice into Dropwizard -- it let us have an application in a fat jar, and let the configuration drive the behavior of the application via loading different Guice modules and running specific code at injection time.
It's been long enough since I played in GWizard that I'm having a hard time picturing how applicable/useful a similar approach might be for gwizard itself.... Probably not much, since the configuration is something defined by the GWizard application, rather than anything dictated by the framework.
-Steve