首页 > 解决方案 > 在 Java 中使用 MapBinder 提供多个绑定

问题描述

我正在使用 Google 的 MapBinders 将事件侦听器(我自己的自定义接口)映射到 EventType。

            MapBinder<EventType, EventListener> eventEventHandlerMapBinder =
                    MapBinder.newMapBinder(binder(), EventType.class, EventListener.class);
            eventEventHandlerMapBinder
                    .addBinding(EventType.DUMMY_EVENT)
                    .to(DummyListener.class);

这让我可以注入Map<EventType, Provider<EventListener>> eventEventHandlerMapBinder我的 EventRegistry 或任何地方。我现在想将多个 EventListener 映射到一个事件类型,即对于 DUMMY_EVENT,我希望绑定 DummyListener.class 和 AnotherDummyListener.class。我怎么做?我不能这样做,因为 MapBinder 为 V 创建了一个提供程序:

    MapBinder<EventType, List> eventEventHandlerMapBinder2 =
            MapBinder.newMapBinder(binder(), EventType.class, List.class);
    eventEventHandlerMapBinder2
            .addBinding(EventType.DUMMY_EVENT)
            .to((Key<? extends List>) Arrays.asList(DummyListener.class, AnotherDummyListener.class));

标签: javaguice

解决方案


您可以使用MapBinderand的组合Multibinder(但您需要从 to 切换ListSet但我想这应该不是问题)。这是一个简单的示例:

    interface Service {
    }
    static class Service1 implements Service {
    }
    static class Service2 implements Service {
    }
    public static void main(String[] args) {
        var injector = Guice.createInjector(new AbstractModule() {
            @Override
            protected void configure() {
                var multibinder = Multibinder.newSetBinder(binder(), Service.class);
                multibinder.addBinding().to(Service1.class);
                multibinder.addBinding().to(Service2.class);

                var mapBinder = MapBinder.newMapBinder(binder(), new TypeLiteral<String>() {}, new TypeLiteral<Set<Service>>() {});
                mapBinder.addBinding("foo").to(Key.get(new TypeLiteral<Set<Service>>(){}));
            }
        });
        var map = injector.getInstance(Key.get(new TypeLiteral<Map<String, Set<Service>>>() {
        }));
        assert map.get("foo") != null;
    }

要区分不同Set的s,可以使用注解,例如@Named/Names或使用自定义的。


推荐阅读