CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-google-inject--guice

Lightweight dependency injection framework for Java 8 and above that eliminates factories and the use of 'new' through @Inject annotation

Pending
Overview
Eval results
Files

types-keys.mddocs/

Type System & Keys

Type-safe dependency identification system supporting generic types and binding annotations for distinguishing multiple bindings of the same type.

Capabilities

Key Class

Identifies a dependency that can be resolved by the Injector, combining type information with optional binding annotations.

/**
 * Identifies a dependency that can be resolved by the Injector.
 * A key is composed of a type and optional binding annotation.
 * @param <T> Type of the dependency
 */
public class Key<T> {
    /**
     * Creates a key for the given type.
     * @param type Class type
     * @return Key for the type
     */
    public static <T> Key<T> get(Class<T> type);
    
    /**
     * Creates a key for the given type with annotation type.
     * @param type Class type
     * @param annotationType Binding annotation type
     * @return Key for the type with annotation
     */
    public static <T> Key<T> get(Class<T> type, Class<? extends Annotation> annotationType);
    
    /**
     * Creates a key for the given type with annotation instance.
     * @param type Class type
     * @param annotation Binding annotation instance
     * @return Key for the type with annotation
     */
    public static <T> Key<T> get(Class<T> type, Annotation annotation);
    
    /**
     * Creates a key for the given type.
     * @param type Type instance
     * @return Key for the type
     */
    public static Key<?> get(Type type);
    
    /**
     * Creates a key for the given type with annotation type.
     * @param type Type instance
     * @param annotationType Binding annotation type
     * @return Key for the type with annotation
     */
    public static Key<?> get(Type type, Class<? extends Annotation> annotationType);
    
    /**
     * Creates a key for the given type with annotation instance.
     * @param type Type instance
     * @param annotation Binding annotation instance
     * @return Key for the type with annotation
     */
    public static Key<?> get(Type type, Annotation annotation);
    
    /**
     * Creates a key for the given type literal.
     * @param typeLiteral Type literal
     * @return Key for the type literal
     */
    public static <T> Key<T> get(TypeLiteral<T> typeLiteral);
    
    /**
     * Creates a key for the given type literal with annotation type.
     * @param typeLiteral Type literal
     * @param annotationType Binding annotation type
     * @return Key for the type literal with annotation
     */
    public static <T> Key<T> get(TypeLiteral<T> typeLiteral, Class<? extends Annotation> annotationType);
    
    /**
     * Creates a key for the given type literal with annotation instance.
     * @param typeLiteral Type literal
     * @param annotation Binding annotation instance
     * @return Key for the type literal with annotation
     */
    public static <T> Key<T> get(TypeLiteral<T> typeLiteral, Annotation annotation);
    
    /**
     * Returns the type literal for this key.
     * @return TypeLiteral representing the type
     */
    public TypeLiteral<T> getTypeLiteral();
    
    /**
     * Returns the binding annotation type, or null if none.
     * @return Annotation type or null
     */
    public Class<? extends Annotation> getAnnotationType();
    
    /**
     * Returns the binding annotation instance, or null if none.
     * @return Annotation instance or null
     */
    public Annotation getAnnotation();
    
    /**
     * Creates a new key with the same annotation but different type.
     * @param type New type
     * @return Key with new type
     */
    public <U> Key<U> ofType(Class<U> type);
    
    /**
     * Creates a new key with the same annotation but different type.
     * @param type New type
     * @return Key with new type
     * @since 3.0
     */
    public Key<?> ofType(Type type);
    
    /**
     * Creates a new key with the same annotation but different type literal.
     * @param typeLiteral New type literal
     * @return Key with new type literal
     * @since 3.0
     */
    public <U> Key<U> ofType(TypeLiteral<U> typeLiteral);
    
    /**
     * Returns a new key of the same type with the specified annotation.
     * @param annotationType Annotation type to use
     * @return Key with specified annotation
     * @since 5.0
     */
    public Key<T> withAnnotation(Class<? extends Annotation> annotationType);
    
    /**
     * Returns a new key of the same type with the specified annotation.
     * @param annotation Annotation instance to use
     * @return Key with specified annotation
     * @since 5.0
     */
    public Key<T> withAnnotation(Annotation annotation);
    
    /**
     * Returns true if this key has binding annotation attributes.
     * @return true if annotated
     */
    public boolean hasAttributes();
    
    /**
     * Returns a key without annotation attributes.
     * @return Key without attributes
     */
    public Key<T> withoutAttributes();
}

Usage Examples:

import com.google.inject.*;
import com.google.inject.name.*;

// Simple type keys
Key<String> stringKey = Key.get(String.class);
Key<DatabaseService> dbKey = Key.get(DatabaseService.class);

// Generic type keys
Key<List<String>> listKey = Key.get(new TypeLiteral<List<String>>() {});
Key<Map<String, Object>> mapKey = Key.get(new TypeLiteral<Map<String, Object>>() {});

// Keys with annotations
Key<String> namedKey = Key.get(String.class, Names.named("database.url"));
Key<Cache> primaryCache = Key.get(Cache.class, Names.named("primary"));

// Custom annotation keys
Key<Logger> loggerKey = Key.get(Logger.class, LoggerFor.class);

// Using keys with injector
DatabaseService db = injector.getInstance(Key.get(DatabaseService.class));
String dbUrl = injector.getInstance(Key.get(String.class, Names.named("database.url")));
List<String> items = injector.getInstance(Key.get(new TypeLiteral<List<String>>() {}));

TypeLiteral Class

Represents generic types at runtime, overcoming Java's type erasure limitations.

/**
 * Represents a generic type T. Java doesn't yet provide a way to represent 
 * generic types, so this class does. Forces clients to create a subclass 
 * which enables retrieval of the type information even at runtime.
 * @param <T> Generic type
 */
public class TypeLiteral<T> {
    /**
     * Creates a type literal for the given class.
     * @param type Class type
     * @return TypeLiteral for the class
     */
    public static <T> TypeLiteral<T> get(Class<T> type);
    
    /**
     * Creates a type literal for the given type.
     * @param type Type instance
     * @return TypeLiteral for the type
     */
    public static TypeLiteral<?> get(Type type);
    
    /**
     * Returns the raw (non-generic) type for this type.
     * @return Raw type
     */
    public Class<? super T> getRawType();
    
    /**
     * Returns the underlying Type instance.
     * @return Type instance
     */
    public Type getType();
    
    /**
     * Returns the generic form of supertype. For example, if this is 
     * ArrayList<String>, this returns Iterable<String> given the input Iterable.class.
     * @param supertype a superclass of, or interface implemented by, this
     * @return TypeLiteral for the supertype
     * @since 2.0
     */
    public TypeLiteral<?> getSupertype(Class<?> supertype);
    
    /**
     * Returns the resolved generic type of field.
     * @param field a field defined by this or any superclass
     * @return TypeLiteral for the field type
     * @since 2.0
     */
    public TypeLiteral<?> getFieldType(Field field);
    
    /**
     * Returns the resolved generic parameter types of methodOrConstructor.
     * @param methodOrConstructor a method or constructor defined by this or any supertype
     * @return List of TypeLiterals for parameter types
     * @since 2.0
     */
    public List<TypeLiteral<?>> getParameterTypes(Member methodOrConstructor);
    
    /**
     * Returns the resolved generic exception types thrown by methodOrConstructor.
     * @param methodOrConstructor a method or constructor defined by this or any supertype
     * @return List of TypeLiterals for exception types
     * @since 2.0
     */
    public List<TypeLiteral<?>> getExceptionTypes(Member methodOrConstructor);
    
    /**
     * Returns the resolved generic return type of method.
     * @param method a method defined by this or any supertype
     * @return TypeLiteral for the return type
     * @since 2.0
     */
    public TypeLiteral<?> getReturnType(Method method);
}

Usage Examples:

import com.google.inject.*;
import java.util.*;

// Create type literals for generic types
TypeLiteral<List<String>> stringListType = new TypeLiteral<List<String>>() {};
TypeLiteral<Map<String, Integer>> mapType = new TypeLiteral<Map<String, Integer>>() {};
TypeLiteral<Set<User>> userSetType = new TypeLiteral<Set<User>>() {};

// Use with binding
public class CollectionModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(new TypeLiteral<List<String>>() {})
            .toInstance(Arrays.asList("item1", "item2", "item3"));
            
        bind(new TypeLiteral<Map<String, Integer>>() {})
            .toProvider(ConfigMapProvider.class);
    }
}

// Get instances using type literals
List<String> strings = injector.getInstance(Key.get(new TypeLiteral<List<String>>() {}));
Map<String, Integer> config = injector.getInstance(Key.get(new TypeLiteral<Map<String, Integer>>() {}));

// Provider methods with type literals
@Provides
List<DatabaseConnection> provideConnections() {
    return Arrays.asList(
        createConnection("primary"),
        createConnection("secondary")
    );
}

Common Type Patterns

Working with Collections

// Binding collections
public class CollectionModule extends AbstractModule {
    @Override  
    protected void configure() {
        // Bind specific collection types
        bind(new TypeLiteral<List<String>>() {})
            .annotatedWith(Names.named("urls"))
            .toInstance(Arrays.asList("http://api1.com", "http://api2.com"));
            
        bind(new TypeLiteral<Map<String, DatabaseConfig>>() {})
            .toProvider(DatabaseConfigProvider.class)
            .in(Singleton.class);
    }
}

// Injecting collections
public class ApiClient {
    private final List<String> apiUrls;
    private final Map<String, DatabaseConfig> dbConfigs;
    
    @Inject
    public ApiClient(
        @Named("urls") List<String> apiUrls,
        Map<String, DatabaseConfig> dbConfigs
    ) {
        this.apiUrls = apiUrls;
        this.dbConfigs = dbConfigs;
    }
}

Working with Wildcards

// Wildcard type literals
TypeLiteral<List<? extends Animal>> animalList = new TypeLiteral<List<? extends Animal>>() {};
TypeLiteral<Map<String, ? super Number>> numberMap = new TypeLiteral<Map<String, ? super Number>>() {};

// Bounded type parameters
public class GenericService<T extends Serializable> {
    // Implementation
}

// Binding generic services
bind(new TypeLiteral<GenericService<User>>() {})
    .to(new TypeLiteral<UserGenericService>() {});

Converting Between Keys and TypeLiterals

// From TypeLiteral to Key
TypeLiteral<List<String>> typeLiteral = new TypeLiteral<List<String>>() {};
Key<List<String>> key = Key.get(typeLiteral);

// From Key to TypeLiteral  
Key<Map<String, Object>> mapKey = Key.get(new TypeLiteral<Map<String, Object>>() {});
TypeLiteral<Map<String, Object>> extracted = mapKey.getTypeLiteral();

// Working with generic type information
Type type = typeLiteral.getType();
Class<?> rawType = typeLiteral.getRawType(); // Returns List.class

// Type equality
TypeLiteral<List<String>> type1 = new TypeLiteral<List<String>>() {};
TypeLiteral<List<String>> type2 = new TypeLiteral<List<String>>() {};
boolean equal = type1.equals(type2); // true

Install with Tessl CLI

npx tessl i tessl/maven-com-google-inject--guice

docs

advanced.md

annotations.md

core-injection.md

index.md

modules.md

multibindings.md

providers-scopes.md

spi.md

types-keys.md

tile.json