Custom Providers

In Infuse, Provider<T> is a functional interface, which means you can implement it using a lambda expression or a method reference for simplicity. This is particularly useful for cases where you want to customize the instantiation of a dependency.

Example

Let's create a custom provider for a Database instance. This provider will use different configurations based on the context in which it's being injected.

import dev.fumaz.infuse.context.Context;
import dev.fumaz.infuse.provider.Provider;

public class CustomDatabaseProvider implements Provider<Database> {

    @Override
    public Database provide(Context<?> context) {
        if (context.getObject().getClass().isAnnotationPresent(UseTestDatabase.class)) {
            // Provide a test database instance
            return new Database("jdbc:example:testdb");
        }
        
        // Provide a production database instance
        return new Database("jdbc:example:proddb");
    }
    
}

In this example, CustomDatabaseProvider checks the class of the object into which the Database instance is being injected. If it's annotated with @UseTestDatabase, it provides a test database configuration; otherwise, it defaults to a production database configuration.

You can then use this provider in your module like so:

bind(Database.class).toProvider(new CustomDatabaseProvider());

Alternatively, since Provider<T> is a functional interface, you can also define a provider using a lambda expression:

bind(Database.class).toProvider(context -> {
    // Custom logic to provide a Database instance
    return new Database("jdbc:example:dynamicdb");
});

This approach allows for more concise and flexible definitions of providers, making it easier to tailor the creation of objects to the specific needs of your application.

Last updated