Magical Provider Guice

Magical ways to bind in Guice.

License

License

Categories

Categories

IDE Development Tools GUI User Interface Guice Application Layer Libs Dependency Injection
GroupId

GroupId

com.github.mlk
ArtifactId

ArtifactId

magical-provider-guice
Last Version

Last Version

1.0.2
Release Date

Release Date

Type

Type

jar
Description

Description

Magical Provider Guice
Magical ways to bind in Guice.
Project URL

Project URL

https://github.com/mlk/magical-provider-guice
Source Code Management

Source Code Management

http://github.com/mlk/magical-provider-guice

Download magical-provider-guice

How to add to project

<!-- https://jarcasting.com/artifacts/com.github.mlk/magical-provider-guice/ -->
<dependency>
    <groupId>com.github.mlk</groupId>
    <artifactId>magical-provider-guice</artifactId>
    <version>1.0.2</version>
</dependency>
// https://jarcasting.com/artifacts/com.github.mlk/magical-provider-guice/
implementation 'com.github.mlk:magical-provider-guice:1.0.2'
// https://jarcasting.com/artifacts/com.github.mlk/magical-provider-guice/
implementation ("com.github.mlk:magical-provider-guice:1.0.2")
'com.github.mlk:magical-provider-guice:jar:1.0.2'
<dependency org="com.github.mlk" name="magical-provider-guice" rev="1.0.2">
  <artifact name="magical-provider-guice" type="jar" />
</dependency>
@Grapes(
@Grab(group='com.github.mlk', module='magical-provider-guice', version='1.0.2')
)
libraryDependencies += "com.github.mlk" % "magical-provider-guice" % "1.0.2"
[com.github.mlk/magical-provider-guice "1.0.2"]

Dependencies

compile (1)

Group / Artifact Type Version
com.google.inject : guice jar 4.0

test (4)

Group / Artifact Type Version
junit : junit jar 4.12
com.netflix.feign : feign-core jar 8.15.1
com.netflix.feign : feign-gson jar 8.15.1
org.mockito : mockito-all jar 1.9.5

Project Modules

There are no modules declared in this project.

Build Status codecov.io

magical-provider-guice

Helper Guice modules.

Robotic Legs Module

This is to provide a simplified API around creating "robot legs", where you have two (or more) similar, but slightly differents trees of objects.

External Creation Module

This is to support creation of a number of objects where something other than guice creates the objects. For example Feign or JDBI where the code is an interface with metadata and Feign or JDBI create the objects via Proxy API.

For examples of this please look at jdbi-guice and feign-guice.

Legacy Module

This is in response to a post on Stack Overflow. The OP wanted a method of creating legacy components without creating either Providers or using Provides Methods.

For this we will assume that we have a legacy components that we can not change. For example:

interface LegacyAction {
}

class LegacyService {
    public LegacyService(String host, int port, LegacyAction action) {
    }
}

Its dependencies (host, port and LegacyAction) are all known by Guice. We want to have Guice also manage LegacyService.

class ModernAction implements LegacyAction {
    @Inject
    ModernAction() {}
}

public class Example {
    public static void main(String... argv) {
        Guice.createInjector(
                new AbstractModule() {
                    @Override
                    protected void configure() {
                        bind(String.class).annotatedWith(named("host")).toInstance("example.com");
                        bind(int.class).annotatedWith(named("port")).toInstance(8080);
                        bind(LegacyAction.class).to(ModernAction.class);

                        bind(LegacyService.class).toProvider(new MagicalLegacyProvider<>(LegacyService.class,
                                Key.get(String.class, named("host")), Key.get(int.class, named("port")), Key.get(LegacyAction.class)));
                    }
                }).getInstance(LegacyService.class);
    }
}

Alternatives

Provider Methods

class ExampleWithProviderMethods {
    public static void main(String... argv) {
        Guice.createInjector(
                new AbstractModule() {
                    @Provides
                    public LegacyService create(@Named("host") String host, @Named("port") int port, LegacyAction action) {
                        return new LegacyService(host, port, action);
                    }

                    @Override
                    protected void configure() {
                        bind(String.class).annotatedWith(named("host")).toInstance("example.com");
                        bind(int.class).annotatedWith(named("port")).toInstance(8080);
                        bind(LegacyAction.class).to(ModernAction.class);
                    }
                }).getInstance(LegacyService.class);
    }
}

This requires a tiny amount of additional typing, but gives you type safety. I'd recommend this in most cases!

Constructor Binding

class ExampleWithConstructorBinding {
    public static void main(String... argv) {
        Guice.createInjector(
                new AbstractModule() {
                    @Override
                    protected void configure() {
                        bind(String.class).toInstance("example.com");
                        bind(int.class).toInstance(8080);
                        bind(LegacyAction.class).to(ModernAction.class);
                        try {
                            bind(LegacyService.class).toConstructor(LegacyService.class.getConstructor(String.class, int.class, LegacyAction.class));
                        } catch (NoSuchMethodException e) {
                            addError(e);
                        }
                    }
                }).getInstance(LegacyService.class);
    }
}

This works find if you have no binding annotations.

Oddities

  • It does not know the difference between int and Integer and will bind to the first on it finds.

Download

Download

Maven:

<dependency>
  <groupId>com.github.mlk</groupId>
  <artifactId>magical-provider-guice</artifactId>
  <version>1.0.1</version>
</dependency>

Apache Buildr

'com.github.mlk:magical-provider-guice:jar:1.0.1'

Apache Ivy

<dependency org="com.github.mlk" name="magical-provider-guice" rev="1.0.1" />

Groovy Grape

@Grapes( 
@Grab(group='com.github.mlk', module='magical-provider-guice', version='1.0.1') 
)

Gradle/Grails

compile 'com.github.mlk:magical-provider-guice:1.0.1'

Scala SBT

libraryDependencies += "com.github.mlk" % "magical-provider-guice" % "1.0.1"

Leiningen

[com.github.mlk/magical-provider-guice "1.0.0"]

** Plain old download **

Versions

Version
1.0.2
1.0.1
1.0.0