When does dependency injection work?
I'm just getting started with writing IntelliJ plugins and decided to simplify the example slightly using dependency injection:
public SayHelloAction(MyPlugin plugin) {
this.plugin = plugin;
}
public void actionPerformed(AnActionEvent e) {
logger.info("SayHelloAction.actionPerformed called");
plugin.sayHello();
}
However, this doesn't work:
ERROR - com.intellij.ide.IdeEventQueue - Original exception:
java.lang.InstantiationException: com.google.jsearch.plugin.SayHelloAction
at java.lang.Class.newInstance0(Class.java:335)
at java.lang.Class.newInstance(Class.java:303)
at com.intellij.openapi.actionSystem.impl.ActionManagerImpl.a(ActionManagerImpl.java:182)
at com.intellij.openapi.actionSystem.impl.ActionManagerImpl.a(ActionManagerImpl.java:316)
at com.intellij.openapi.actionSystem.impl.ActionManagerImpl.getAction(ActionManagerImpl.java:23)
at com.intellij.openapi.actionSystem.DefaultActionGroup.getChildren(DefaultActionGroup.java:227)
...
Is dependency injection supposed to work for actions? When can I expect it to work?
Please sign in to leave a comment.
This does currently not work for Actions. It only works for Components (Application, Project, Module). There's a feature request you can vote for though: http://www.jetbrains.net/jira/browse/IDEABKL-5121
Sascha
What about the extension point mechanism? How does that relate to the (picocontainer-based?) dependency injection?
You're right, it seems that extensions (e.g. projectService, colorSettingsPage, etc.) can also make use of DI.
Sascha
1) So what is the "scope" (application, project, module) that is used for extensions?
2) In addition, I've had the following situation a few times in a plugin module:
-I have an extension point implementation (that's called by IDEA core)
-Somewhere in one of my components, I'd like to access that extension point as well.
If I remember correctly, it wasn't possible to dependency-inject my own extension point into a "regular" component. I assume there are two approaches to work around this:
a) move the logic from the extension point into a regular component, then dependency-inject the component into the extension point (the extension point implementation class will now become a thin wrapper around the injected component).
b) (inside my component) somehow ask the extension point API to retrieve my specific extenion point implementation. I remember searching the extension point APIs for this, but not finding anything.
I believe it depends on which area declares the extension point. See lib\resources.jar!\META-INF\plugin.xml, e.g. "highlightVisitor". Without such an area, it belongs to the root-area, which seems to be the application scope.
Yes, that is correct. Extensions are not available as DI dependencies, but can be obtained through
com.intellij.openapi.extensions.ExtensionsArea.getExtensionPoint(epName)
where the ExtensionsArea instance can be obtained from com.intellij.openapi.extensions.Extensions.getRootArea() or com.intellij.openapi.extensions.Extensions.getArea(Module or Project instance).
I hope that helps a bit, though for deeper details you're probably better off asking Mike or Dmitry ;)
Sascha
Hello Sascha,
In fact the most convenient API for this is:
Extensions.getExtensions(ExtensionPointName, AreaInstance)
Type-safe and no need to bother with getArea() - you can pass Project or
Module directly.
--
Dmitry Jemerov
Software Developer
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"