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