I'm writing a Java package to interact with a dynamo table, and I'm using Guice for DI. The package exposes a client to its users as follows -
// External client
public class Client {
    DataManager manager;
    public static Client getClient() {
        return Guice.createInjector(new MyModule()).getInstance(Client.class);
    }
}
// Manager class to interact with dynamo
public class DataManager {
    AmazonDynamoDb amazonDynamoDb;
    DynamoDbMapper dynamoDbMapper;
    @Time // IMPORTANT - This is AOP style metric recording which records the amount of time taken to do a particular operation
    public void addRecord();
    public void deleteRecord();
    ...
}
// Class that represents an entry in the table
public class Data {
}
One of the use cases is that a table check has to performed before the client instance is returned to the users of this package. Which basically means that I have to call an initializeTable() function somewhere in my code. My question is where should I put that logic?
- In the constructor? Probably not because violates DI principles of doing only wiring in constructors, and makes testing difficult.
- Inside a Guice module? I could create a @Provides function that initializes the client and before returning it, runs the init() function. But a limiting factor here is that I have AOP style annotations that won't work if the object instances are not created by Guice itself.
What I ended up doing was this (performing injection on a module itself which would be registered with Guice in the Client#getClient() method)-
public class InitializingModule extends AbstractModule {
/**
 * Perform injection on this instance so that the table initialization happens before any usable class is
 * returned to the clients of this package.
 */
@Override
protected void configure() {
    requestInjection(this);
}
/**
 * Configure dynamoDB to check for and initialize the table.
 *
 * @param startupUtil
 * @throws Exception
 */
@Inject
void configureDynamo(DynamoStartupUtil startupUtil) throws Exception {
    startupUtil.initialize();
}
}
So where is this initialization logic supposed to go so that the principles of DI are not violated and the classes are easily testable? Note that Guice does not support @PostConstruct yet.
