001package io.avaje.inject.spi;
002
003import io.avaje.inject.BeanScope;
004import jakarta.inject.Provider;
005
006import java.lang.reflect.Type;
007import java.util.List;
008import java.util.Optional;
009import java.util.Set;
010import java.util.function.Consumer;
011
012/**
013 * Mutable builder object used when building a bean scope.
014 */
015public interface Builder {
016
017  /**
018   * Create the root level Builder.
019   *
020   * @param suppliedBeans The list of beans (typically test doubles) supplied when building the context.
021   * @param enrichBeans   The list of classes we want to have with mockito spy enhancement
022   * @param parent        The parent BeanScope
023   */
024  @SuppressWarnings("rawtypes")
025  static Builder newBuilder(List<SuppliedBean> suppliedBeans, List<EnrichBean> enrichBeans, BeanScope parent) {
026    if (suppliedBeans.isEmpty() && enrichBeans.isEmpty()) {
027      // simple case, no mocks or spies
028      return new DBuilder(parent);
029    }
030    return new DBuilderExtn(parent, suppliedBeans, enrichBeans);
031  }
032
033  /**
034   * Return true if the bean should be created and registered with the context.
035   * <p/>
036   * Returning false means there has been a supplied bean already registered and
037   * that we should skip the creation and registration for this bean.
038   *
039   * @param name  The qualifier name
040   * @param types The types that the bean implements and provides
041   */
042  boolean isAddBeanFor(String name, Type... types);
043
044  /**
045   * Return true if the bean should be created and registered with the context.
046   * <p/>
047   * Returning false means there has been a supplied bean already registered and
048   * that we should skip the creation and registration for this bean.
049   *
050   * @param types The types that the bean implements and provides
051   */
052  boolean isAddBeanFor(Type... types);
053
054  /**
055   * Register the bean instance into the context.
056   *
057   * @param bean The bean instance that has been created.
058   */
059  <T> T register(T bean);
060
061  /**
062   * Register the bean as a Primary bean.
063   */
064  <T> T registerPrimary(T bean);
065
066  /**
067   * Register the bean as a secondary bean.
068   */
069  <T> T registerSecondary(T bean);
070
071  /**
072   * Register the externally provided bean.
073   *
074   * @param type The type of the provided bean.
075   * @param bean The bean instance
076   */
077  <T> void withBean(Class<T> type, T bean);
078
079  /**
080   * Add lifecycle PostConstruct method.
081   */
082  void addPostConstruct(Runnable runnable);
083
084  /**
085   * Add lifecycle PreDestroy method.
086   */
087  void addPreDestroy(AutoCloseable closeable);
088
089  /**
090   * Add field and method injection.
091   */
092  void addInjector(Consumer<Builder> injector);
093
094  /**
095   * Get an optional dependency.
096   */
097  <T> Optional<T> getOptional(Class<T> cls);
098
099  /**
100   * Get an optional named dependency.
101   */
102  <T> Optional<T> getOptional(Class<T> cls, String name);
103
104  /**
105   * Get an optional dependency potentially returning null.
106   */
107  <T> T getNullable(Class<T> cls);
108
109  /**
110   * Get an optional named dependency potentially returning null.
111   */
112  <T> T getNullable(Class<T> cls, String name);
113
114  /**
115   * Return Provider of T given the type.
116   */
117  <T> Provider<T> getProvider(Class<T> cls);
118
119  /**
120   * Return Provider of T given the type and name.
121   */
122  <T> Provider<T> getProvider(Class<T> cls, String name);
123
124  /**
125   * Return Provider for a generic interface type.
126   *
127   * @param cls  The usual implementation class
128   * @param type The generic interface type
129   */
130  <T> Provider<T> getProviderFor(Class<?> cls, Type type);
131
132  /**
133   * Get a dependency.
134   */
135  <T> T get(Class<T> cls);
136
137  /**
138   * Get a named dependency.
139   */
140  <T> T get(Class<T> cls, String name);
141
142  /**
143   * Get a list of dependencies for the interface type .
144   */
145  <T> List<T> list(Class<T> interfaceType);
146
147  /**
148   * Get a set of dependencies for the interface type .
149   */
150  <T> Set<T> set(Class<T> interfaceType);
151
152  /**
153   * Build and return the bean scope.
154   */
155  BeanScope build(boolean withShutdownHook);
156}