Extension to Google Guice that provides contribution methods
Switch branches/tags
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
crayon-core
crayon-lib-services
.gitignore
LICENSE
README.md
pom.xml

README.md

Crayon

Crayon is an extension to Google Guice that provides the ability to define contribution methods. A contribution method is called after the Guice Injector has been created and can use any binding defined.

The main library is crayon-core and is available in Maven-central:

<dependency>
  <groupId>se.l4.crayon</groupId>
  <artifactId>crayon-core</artifactId>
  <version>0.7</version>
</dependency>

Defining a contribution

Methods are defined in Guice modules. Either by extending CrayonModule or by creating a CrayonBinder directly.

Extending CrayonModule:

public class TestModule extends CrayonModule {
  public void configure() {
    // Do normal Guice configuration here
  }
}

Using CrayonBinder:

public class TestModule extends AbstractModule {
  public void configure() {
    // Activate support for contributions
    CrayonBinder.newBinder(binder, this);

    // Do normal Guice configuration here
  }
}

Example of defining a contribution method:

@Contribution
public void contributeService(ServiceManager manager, TestService service) {
  manager.add(service);
}

The order at which contributions are invoked can be configured:

@Contribution
@Named("service:test")
public void contributeService(ServiceManager manager, TestService service) {
  manager.add(service);
}

@Contribution
@Before("service:test")
public contributeOtherService(ServiceManager manager, OtherService service) {
  // This will run before the contribution named "service:test" 
  manager.add(service);
}

Calling the contributions

Call the contributions by calling Crayon.start():

Injector injector = Guice.createInjector(...);
Crayon crayon = injector.getInstance(Crayon.class);
crayon.start();

You can also use Configurator to create a your Injector in which case Crayon.start() will be called automatically.

Injector injector = new Configurator(stage)
  .add(SomeModule.class)
  .add(new OtherModule())
  .configure();

Custom contributions

It is possible to use any annotation as a marker for a contribution. This is useful when building libraries where more detailed control of contributions is needed. When a custom annotation is used the library author has full control over when the defined methods are run.

First define a custom binding annotation. This method is then used instead of @Contribution when contributions are defined.

In the consuming module call bindContributions(Class<? extends Annotation>) (on either CrayonModule or CrayonBinder). This will bind an instance of Contributions annotated with custom annotation. When desired you can then call the run method on the Contributions instance.

Example:

@BindingAnnotation
@Target({ ElementType.METHOD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface StorageContribution
{
}

Module that triggers contributions:

public class StorageModule extends CrayonModule {
  public void configure() {
    bindContributions(StorageContribution.class);
    
    // Other configuration here
  }
  
  @Contribution
  public void runStorageContributions(@StorageContribution Contributions contributions) {
    contributions.run();
  }
}
public class StorageExtensionModule extends CrayonModule {
  public void configure() {
  }
  
  @StorageContribution
  public void contributeSomeStorageStuff() {
    // This method is run when the contributions are triggered by StorageModule
  }
}