In
javax
, if you use@Inject
into a constructor, but you have instances where you can't pass those parameters, what do you do?@ApplicationScoped public class JavascriptLanguageExecutor extends LanguageExecutor { @Inject JavascriptLanguageExecutor(EngineInstance engine) { super(Language.JAVASCRIPT, engine.instance); } } public enum Language { JAVASCRIPT("js"); public LanguageExecutor getExecutor() { return switch (this) { // THIS NEEDS "EngineInstance" BUT I DON'T HAVE ABILITY TO "@Inject" INTO ENUMS case JAVASCRIPT -> new JavascriptLanguageExecutor(); }; }
So here this
EngineInstance
is available via injection in the app but you can't use this inside of enums I think, and so I can't actually instantiate the class there.Could I move it out of the constructor and do a field injection
In that case, you need to pass an EngineInstance.
Sounds dumb, but yeah. Ignore all the javax requirements for a second, since they aren't super relevant.
public class JavascriptLanguageExecutor extends LanguageExecutor {
JavascriptLanguageExecutor(EngineInstance engine) {
super(Language.JAVASCRIPT, engine.instance);
}
}
What you want is, effectively, a map of Language -> Executor. So just make one.
= new EnumMap<Language, LanguageExecutor>(...); var executors
And then pass it around where you need it.
There are more options but generally speaking Java is structured in a way where passing the thing is the path of least resistance. Unless you made your LanguageExecutors work with the service provider stuff, but that's somewhat niche (for application code).
Im not gonna pretend you can't also have a static map and fill it up with instances - you can. Just then you need to be careful of when it is hydrated vs. uninitialized and make sure to synchronize if you need to etc.