@@ -0,0 +1,2518 @@
+package joshng.util.guice;%0A%0Aimport com.google.inject.Binder;%0Aimport com.google.inject.Injector;%0Aimport com.google.inject.Key;%0Aimport com.google.inject.Module;%0Aimport com.google.inject.TypeLiteral;%0Aimport com.google.inject.multibindings.Multibinder;%0Aimport joshng.util.collect.Ref;%0Aimport joshng.util.concurrent.services.BaseService;%0Aimport joshng.util.concurrent.services.ServiceDependencyManager;%0A%0Aimport javax.inject.Inject;%0Aimport javax.inject.Provider;%0Aimport java.util.Set;%0A%0Aimport static joshng.util.collect.Functional.extend;%0A%0A/**%0A * User: josh%0A * Date: 11/30/15%0A * Time: 1:32 PM%0A */%0Apublic enum ManagedServicesModule implements Module %7B%0A  INSTANCE;%0A%0A  private static TypeLiteral%3CRef%3CKey%3C? extends BaseService%3C?%3E%3E%3E%3E MANAGED_SERVICE_KEY_TYPE = new TypeLiteral%3CRef%3CKey%3C? extends BaseService%3C?%3E%3E%3E%3E() %7B %7D;%0A%0A  @Override public void configure(Binder binder) %7B%0A    binder.bind(ServiceDependencyManager.class).toProvider(ServiceDependencyManagerProvider.class).asEagerSingleton();%0A    manager(binder); // ensure multibinder is defined even if no services are managed%0A  %7D%0A%0A  public static ManagedServiceBinder manager(Binder binder) %7B%0A    binder.install(INSTANCE);%0A    return new ManagedServiceBinder(binder);%0A  %7D%0A%0A  static class ServiceDependencyManagerProvider implements Provider%3CServiceDependencyManager%3E %7B%0A    private final Injector injector;%0A    private final Set%3CRef%3CKey%3C? extends BaseService%3C?%3E%3E%3E%3E managedServiceKeyRefs;%0A%0A    @Inject%0A    ServiceDependencyManagerProvider(Injector injector, Set%3CRef%3CKey%3C? extends BaseService%3C?%3E%3E%3E%3E managedServiceKeyRefs) %7B%0A      this.injector = injector;%0A      this.managedServiceKeyRefs = managedServiceKeyRefs;%0A    %7D%0A%0A    @Override public ServiceDependencyManager get() %7B%0A      return GuiceDependencyGraph.buildServiceDependencyManager(%0A              injector,%0A              extend(managedServiceKeyRefs).map(Ref::get));%0A    %7D%0A  %7D%0A%0A  public static class ManagedServiceBinder %7B%0A    private final Multibinder%3CRef%3CKey%3C? extends BaseService%3C?%3E%3E%3E%3E multibinder;%0A%0A    private ManagedServiceBinder(Binder binder) %7B%0A      multibinder = Multibinder.newSetBinder(binder, MANAGED_SERVICE_KEY_TYPE);%0A    %7D%0A%0A    public void manage(Class%3C? extends BaseService%3C?%3E%3E implementation) %7B%0A      manage(Key.get(implementation));%0A    %7D%0A%0A    public void manage(TypeLiteral%3C? extends BaseService%3C?%3E%3E implementation) %7B%0A      manage(Key.get(implementation));%0A    %7D%0A%0A    public void manage(Key%3C? extends BaseService%3C?%3E%3E targetKey) %7B%0A      multibinder.addBinding().toInstance(Ref.of(targetKey));%0A    %7D%0A  %7D%0A%7D%0A

introduce ManagedServicesModule