0

When using Guice, how to restrict clients to getting instances from a specific group of classes (aka the Facebook problem)?

Imagine I architect my system using ports-and-adapters and I have an admin adapter side, a business logic component, and a data-access side used by the business component. How to allow clients only to get instances of the interfaces on the admin adapter side?

In code:

The admin adapter:

public interface Admin { /* ... */ }

class AdminImpl implements Admin {
    @Inject
    AdminImpl(BusLogic bl) { /* .... */ }
    /* ... */
}

The business logic:

public interface BusLogic { /* ... */ }

I would like to make the injector at the app level only return instances of the Admin interface.

Thanks

beluchin
  • 9,529
  • 3
  • 22
  • 32

1 Answers1

1

Ah, PrivateModule is one answer. One PrivateModule at the app level which exposes only the Admin interface:

public class PrivateModuleTest {
    public static interface Admin {}

    public static class AdminImpl implements Admin {
        @Inject
        public AdminImpl(BusLogic x) {}
    }

    public static interface BusLogic {}

    public static class BusLogicImpl implements BusLogic {}

    public static class AdminModule extends AbstractModule {
        @Override
        protected void configure() {
            bind(Admin.class).to(AdminImpl.class);
        }
    }

    public static class BusLogicModule extends AbstractModule {
        @Override
        protected void configure() {
            bind(BusLogic.class).to(BusLogicImpl.class);
        }
    }

    public static class AppModule extends PrivateModule {
        @Override
        protected void configure() {
            install(new AdminModule());
            expose(Admin.class);  // <---- clients may instantiate only this type

            install(new BusLogicModule());
        }
    }

    @Test
    public void exposeAdmin() {
        Guice.createInjector(new AppModule())
                .getInstance(Admin.class);
    }

    @Test(expected = ConfigurationException.class)
    public void doNotExposeBusLogic() {
        Guice.createInjector(new AppModule())
                .getInstance(BusLogic.class);
    }
}
beluchin
  • 9,529
  • 3
  • 22
  • 32