All Downloads are FREE. Search and download functionalities are using the official Maven repository.

se.ansman.dagger.auto.BindGenericAs.kt Maven / Gradle / Ivy

package se.ansman.dagger.auto

/**
 * How generic types are bound when using multibinding such as [AutoBindIntoSet] or [AutoBindIntoMap].
 *
 * The default is [ExactType] unless the bound type is annotated with [Default] in which case that is used
 * as the default.
 *
 * @since 1.0.0
 */
public enum class BindGenericAs {
    /**
     * Only the exact supertype is bound. For example, if the type is `List` then only `List` is bound.
     *
     * This is the default unless the target type is annotated with [Default].
     */
    ExactType,

    /**
     * The type is bound as a wildcard type. For example, if the type is `List` then it's bound as `List<*>`.
     */
    Wildcard,

    /**
     * The type is bound as the exact supertype and as a wildcard type. For example, if the type is `List` then
     * it's bound as both `List` and `List<*>`.
     */
    ExactTypeAndWildcard;

    /**
     * Specifies the default [AutoBindIntoSet.bindGenericAs] and [AutoBindIntoMap.bindGenericAs] for the annotated type.
     *
     * This is useful if you know that the generic is always unique or if it's always shared.
     * For example, an `Interceptor` should probably be bound as [ExactType] because you want to get all
     * interceptors for a given type where as `Resource` should probably be bound as [Wildcard] since
     * you're likely interested in getting all resources because there are no duplicates.
     *
     * You can only add this to generic types.
     *
     * Example when using wildcard:
     * ```
     * @BindGenericAs.Default(BindGenericAs.Wildcard)
     * interface Resource {
     *   fun produce(): T
     *   fun close()
     * }
     *
     * @AutoBindIntoSet // Will bind this as Resource<*> instead of Resource
     * class SomeResource @Inject constructor() : Resource {
     *   ...
     *   override fun close() { ... }
     * }
     *
     * class ResourceCloser @Inject constructor(
     *   val resources: Set<@JvmSuppressWildcards Resource<*>>
     * ) {
     *   fun closeAllResources() {
     *     resources.forEach { it.close() }
     *   }
     * }
     * ```
     *
     * Example when using exact type:
     * ```
     * @BindGenericAs.Default(BindGenericAs.Type)
     * interface Interceptor {
     *   fun intercept(value: T): T
     * }
     *
     * @AutoBindIntoSet // Will bind this as Interceptor
     * class SomeInterceptor @Inject constructor() : Interceptor {
     *   ...
     * }
     *
     * class SomeOperation @Inject constructor(
     *   val interceptors: Set<@JvmSuppressWildcards Interceptor>
     * ) {
     *   fun performOperation(value: SomeThing): SomeThing {
     *     return interceptors.fold(value) { v, interceptor -> interceptor.intercept(v) }
     *   }
     * }
     * ```
     *
     * @see AutoBindIntoSet
     * @see AutoBindIntoMap
     * @since 1.0.0
     */
    @MustBeDocumented
    @Target(AnnotationTarget.CLASS)
    @Retention(AnnotationRetention.BINARY)
    public annotation class Default(val value: BindGenericAs)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy