Guice提供隐式动态子类

时间:2018-03-21 16:58:47

标签: java dependency-injection guice

我需要帮助,我有一个AbstractModule,其中包含需要使用单个提供程序的子类列表。

我提供的类是作为插件动态加载的

我怎样才能实现这个目标

interface Plugin {X getX();}

class Plugin1 implements Plugin {X getX() {return X1;}}
class Plugin2 implements Plugin {X getX() {return X2;}}


public class ThreadDataModule extends AbstractModule {

    @Override
    protected void configure() {
       //x_list will contain Plugin1,Plugin2,Plugin3 classes 
       for(Plugin plugin : plugin_list_classes) {
         ->> how can i bind  'plugin.getX().class to XProvider' 
       }
    }

    public class XProvider implements Provider<X> {
        public X get() {
            return Get Plugin at Thread.getX()
        }
    }
}

谢谢

============================

我做了类似的事情来解决这个问题,现在每个插件都必须实现getXProvider方法♂️。有更优雅的方式吗?

interface Plugin {
   X getX();
   public Provider getXProvider(Callable callable);
}

class Plugin1 implements Plugin {
    public X getX() {return new X1;}

    @Override
    public Provider getXProvider(Callable callable) {
        return new Provider<X1>() {
            @Override
            public X1 get() {
                try {
                    return (X1) callable.call();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }
        }
    };
}



public class ThreadDataModule extends AbstractModule {

    @Override
    protected void configure() {
       //x_list will contain Plugin1,Plugin2,Plugin3 classes 
       for(Plugin plugin : plugin_list_classes) {
         bind(plugin.getX().getClass()).toProvider((javax.inject.Provider)plugin.getXProvider(()-> {
            return m_threadIndexToDependencies.get(m_threadIndex).X;
           }));
       }
    }
}

2 个答案:

答案 0 :(得分:1)

我认为如果要实现自定义提供程序,则无需在configure中进行绑定。无论是单向还是其他方式。

不确定x_list_classes中的类与线程之间的关系是什么。每个帖子都有一个班级吗?

如果是,那么您想如何进行映射?

通常,您可以进行范围内绑定,以便为每个范围创建单个实例:

https://github.com/google/guice/wiki/Scopes

我认为您也可以将Thread作为范围。

或者您可能希望为每个类添加自定义注释,以便可以为注入注释不同的X实例,如下所示:

PATH=`npm bin`:$PATH webpack --version

然后你需要使用annotatedWith()绑定:

@Inject
public SomeClass(@Foo X x) {}

您也需要自己创建注释,请参阅示例:

https://github.com/google/guice/wiki/BindingAnnotations

答案 1 :(得分:1)

您想要bind(...).toProvider(...)

for (Class<?> targetType : ...) {
    bind(targetType).toProvider(new XProvider(...));
}

如果您想在XProvider课程中注入其他依赖项,您可以使用Binder.getProvider()(或AbstractModule.getProvider(),如果您是<{1}})的子类,或者您可以使AbstractModule本身可注射。

通常,使XProvider本身可注入是更简单的解决方案(只做XProvider),但听起来你想要使用类似逻辑提供多种输出类型,可能想手动实例化提供者对象。