0

I'm writing a web application with a framework that calls the run() method of my Application class and passes in an object of type Environment.

Other objects I'm writing depend on this Environment class, as they need to call its register() and metrics() methods.

The problem is that I create the object graph in the main() function of my application, like this:

public class MainApplication extends Application<MainConfiguration> {

private final ConnectionPool sharedPool;

public static void main(String[] args) throws Exception {
MainApplication mainApplication = DaggerMainApplicationComponent.create()
    .createApplication();

mainApplication.run(args);
}

@Inject public MainApplication(ConnectionPool connectionPool) {
super();
sharedPool = connectionPool;
}

@Override
public void run(MainConfiguration configuration, Environment environment) throws Exception {
    // Here is where I have access to the environment variable
}

So, by the time MainApplication is constructed by Dagger, the environment variable is not ready. It is only when run() is called that it is available.

Is there a way to inject this variable into the object graph at that point?

Parham Doustdar
  • 2,019
  • 3
  • 22
  • 41

1 Answers1

1

This kind of question has already had some traction here but to answer your specific case and to elaborate on EpicPandaForce's comment you can easily escape a small dependency cycle by creating a holder class:

class EnvironmentHolder {

    private Environment environment;

    @Nullable
    Environment get() {
        return environment;
    }

    void set(Environment environment) {
        this.environment = environment;
    }
}

And making the former dependencies of Environment dependencies of EnvironmentHolder instead:

class DependsOnEnvironment {

    private final EnvironmentHolder environmentHolder;

    @Inject
    DependsOnEnvironment(EnvironmentHolder environmentHolder) {
        this.environmentHolder = environmentHolder;
    }

    public void doSomethingWithMetrics() {
        Environment environment = environmentHolder.get();
        if (environment == null) {
            throw new IllegalStateException("Environment object should be available at the injection time of this class");
        }

        Metrics metrics = environment.metrics();
        //etc.
    }
}

If you find yourself using this often it may be a sign that you need a custom scope instead.

David Rawson
  • 20,912
  • 7
  • 88
  • 124