Repository navigation
RestrictedBindingSource
If you own a Guice library that provides a set of bindings, you may want to prevent code outside your library from providing them. Reasons include:
-
Preventing users from rolling their own fake implementation of your bindings in tests, in order to force them to use the canonical fake module your library maintains.
-
Letting alternate implementations of your set of bindings appear throughout your codebase makes it harder to refactor client code.
-
Guaranteeing a contract for downstream libraries. There can be invariants between your bindings that you want to guarantee by only allowing a limited set of vetted implementations - similar to how Guava guarantees the
ImmutableSetcontract by only allowing subclasses within the library.
The @RestrictedBindingSource annotation lets you do this - it lets you
restrict which modules can provide your bindings. Annotating your bindings with
@RestrictedBindingSource lets you specify a permit annotation that modules
providing them need to be annotated with. For example, this is how you would
ensure that @IpAddress Integer and RoutingTable bindings can only be
provided by NetworkModule:
// Modules annotated with this Permit can provide Network bindings.
@RestrictedBindingSource.Permit
@Retention(RetentionPolicy.RUNTIME)
@interface NetworkPermit {}
// Bindings with the @IpAddress qualifier annotation can only be provided by
// modules with the NetworkPermit annotation.
@RestrictedBindingSource(
explanation = "Please install NetworkModule instead of binding network bindings yourself.",
permits = {NetworkPermit.class})
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface IpAddress {}
// The RoutingTable binding can only be provided by modules annotated with the
// NetworkPermit annotation.
@RestrictedBindingSource(
explanation = "Please install NetworkModule instead of binding network bindings yourself.",
permits = {NetworkPermit.class})
public interface RoutingTable {
int getNextHopIpAddress(int destinationIpAddress);
}
@NetworkPermit
public final class NetworkModule extends AbstractModule {
@Provides @IpAddress int provideIp( ... ) { ... }
@Override
protected void configure() {
// RoutingModule is permitted to provide the RoutingTable binding because
// its parent NetworkModule is annotated with NetworkPermit - ie. it's
// enough for any module providing a binding (directly or indirectly) to
// have the right permit.
install(new RoutingModule());
}
}
private final RoutingModule extends AbstractModule {
@Provides RoutingTable provideRoutingTable( ... ) { ... }
}
In addition to modules, ModuleAnnotatedMethodScanners are also a source of
bindings and can be annotated with permits to grant them permission to provide
restricted bindings.
For example, if a scanner scans @FooProvides methods and binds types provided
by those methods to @Foo Type, @Foo can be restricted such that only the
scanner can provide bindings annotated with @Foo.
-
User's Guide
-
Integration
-
Extensions
-
Internals
-
Releases
-
Community