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?

6 comments
Comment actions Permalink

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

0
Comment actions Permalink

What about the extension point mechanism? How does that relate to the (picocontainer-based?) dependency injection?

0
Comment actions Permalink

You're right, it seems that extensions (e.g. projectService, colorSettingsPage, etc.) can also make use of DI.

Sascha

0
Comment actions Permalink

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.

0
Comment actions Permalink

1) So what is the "scope" (application, project, module) that is used for extensions?


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.

If I remember correctly, it wasn't possible to dependency-inject my own extension point into a "regular" component.


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

0
Comment actions Permalink

Hello Sascha,

Yes, that is correct. Extensions are not available as DI dependencies,
but can be obtained through

com.intellij.openapi.extensions.ExtensionsArea.getExtensionPoint(epNam
e)

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).


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!"


0

Please sign in to leave a comment.