以编程方式添加 Eclipse 4 RCP 上下文函数

Add Eclipse 4 RCP context function programmatically

我正在尝试将 Guice 4 注入器与 Eclipse 4 RCP DI 机制桥接起来。 我想做的是创建一个 ContextFunction,它将在 Guice 注入器中查找值并将它们绑定到 IEclipseContext 中,如下所示:

import org.eclipse.e4.core.contexts.ContextFunction;
import org.eclipse.e4.core.contexts.IEclipseContext;

import com.google.inject.Injector;

public class GuiceRCPBridgeFunction  extends ContextFunction 
{
    private Injector injector;

    public GuiceRCPBridgeFunction(Injector injector)
    {
        this.injector = injector;
    }

    @Override
    public Object compute(IEclipseContext context, String contextKey) 
    {
        // convert string key to type:
        Class<?> guiceKey = null;
        try {
            guiceKey = injector.getClass().getClassLoader().loadClass(contextKey);
        } 
        catch (ClassNotFoundException e) { throw new RuntimeException( e ); }

        // get instance from the injector:
        Object instance = injector.getInstance( guiceKey );

        // cache the instance in the eclipse context:
        context.set( contextKey, instance );

        return instance;
    }
}

我想知道是否有办法在创建 Injecter 后附加此函数,这样我就可以避免将 Injecter 本身放入 IEclipseContext 中?

不确定这是否是您的意思,但您可以使用它将获得的对象的键将 ContextFunction 放入 IEclipseContext 中。当 Eclipse 查找该对象时,它将看到该对象是一个 ContextFunction 并调用 compute 方法。

这确实意味着您必须知道上下文函数将要求的所有对象的键。

按照 greg-449 的建议,将函数置于特定键下后,以下似乎有效:

import org.eclipse.e4.core.contexts.ContextFunction;
import org.eclipse.e4.core.contexts.IEclipseContext;

import com.google.inject.Injector;
import com.google.inject.Key;

/**
 * Links guice and e4 RI  
 */
public class GuiceRCPBridgeFunction  extends ContextFunction 
{

    public static void link( Injector injector, IEclipseContext context )
    {
        GuiceRCPBridgeFunction function = new GuiceRCPBridgeFunction(injector);
        // add this function for every injector binding:
        for(Key <?> key : injector.getBindings().keySet())
        {
            String contextKey = key.getTypeLiteral().toString(); 
            Class classKey = function.loadClass( contextKey );
            context.set( classKey, function );
        }
    }

    private Injector injector;

    public GuiceRCPBridgeFunction(Injector injector)
    {
        this.injector = injector;

    }

    @Override
    public Object compute(IEclipseContext context, String contextKey) 
    {
        // convert string key to type:
        Class classKey = loadClass( contextKey );
        // get instance from the injector:
        Object instance = injector.getInstance( classKey );
        // cache the instance in the eclipse context:
        context.set(classKey, instance);

        return instance;
    }

    protected Class <?> loadClass( String className )
    {
        Class<?> guiceKey = null;
        try {
            guiceKey = injector.getClass().getClassLoader().loadClass(className);
        } 
        catch (ClassNotFoundException e) { throw new IllegalArgumentException( e ); }

        return guiceKey;
    }
}