Injecting Environment Variables in Guice
2022-10-31T10:00:00.00Z

The Problem

Sometimes you need to access environment variables from your guice injection framework. For instance, you might want to pull the AWS_REGION environment variable in from your AWS Lambda's execution environment.

A way to do this is to directly bind the environment variable to a named string as follows

class Module1 extends AbstractModule {
    /**
     * Via a method
     **/
    @Named("AWS_REGION")
    @Singleton
    public String getRegion() {
        return System.getenv("AWS_REGION");
    }
};

class Module2 extends AbstractModule {}

    /**
     * Or with binding.
     */
    @Override
    public void configure() {
        bind(String.class)
            .annotatedWith(Names.named("AWS_REGION"))
            .toInstance(System.getenv("AWS_REGION"));
    }
}

There are a couple reasons this is non-ideal

  1. There is no trivial way to override them for testing. You can:
    1. create a test module to override them and have to re-declare all the strings or
    2. Set system environment variables in your tests and risk messing something up.
  2. It's still pretty verbose for more than a couple.

Another way

Enter Guice Environment and EnvModule

EnvModule envModule = EnvModule.builder()
    .add("AWS_REGION")                       //bind AWS_REGION to AWS_REGION
    .rename("CB_VAR1", "var1")               //bind var1 to CB_VAR1
    .add("CB_VAR2", "CB_VAR3")               //bind many at once
    .prefix("coderberry.", CB_VAR4, CB_VAR5) //bind many with a prefix
    .build();

Injector injector = Guice.createInjector(envModule);
//injector now provides strings called
//AWS_REGION, var1, CB_VAR2, CB_VAR3, 
//coderberry.CB_VAR4 and coderberry.CB_VAR5

String variable = injector.getInstance(
        Key.get(String.class, 
        Names.named("AWS_REGION")))
    );

And also properties

Use properties as well with PropModule

PropModule module = PropModule.build(properties)
    .add("PROP1")
    .rename("PROP2", "name2")
    .build();
Copyright 2022, Michael Smit