001package io.dinject.core;
002
003import io.dinject.BeanContext;
004import io.dinject.BeanEntry;
005
006import java.util.List;
007import java.util.Optional;
008import java.util.Set;
009import java.util.function.Consumer;
010
011/**
012 * Mutable builder object used when building a bean context.
013 */
014public interface Builder {
015
016  /**
017   * Return the name of the (module) context this builder is creating.
018   */
019  String getName();
020
021  /**
022   * Return the names of module features that this module provides.
023   */
024  String[] getProvides();
025
026  /**
027   * Return the names of modules that this module depends on.
028   */
029  String[] getDependsOn();
030
031  /**
032   * Set a parent builder that can provide cross-module dependencies.
033   */
034  void setParent(Builder parent);
035
036  /**
037   * Return true if the bean should be created and registered with the context.
038   * <p/>
039   * Returning false means there has been a (test double) bean already registered and
040   * that we should skip the creation and registration for this bean.
041   *
042   * @param addForType   The interface that the bean implements and provides
043   * @param injectTarget The actual bean type we are looking to create and register
044   */
045  boolean isAddBeanFor(Class<?> addForType, Class<?> injectTarget);
046
047  /**
048   * Return true if the bean should be created and registered with the context.
049   * <p/>
050   * Returning false means there has been a (test double) bean already registered and
051   * that we should skip the creation and registration for this bean.
052   *
053   * @param injectTarget The actual bean type we are looking to create and register
054   */
055  boolean isAddBeanFor(Class<?> injectTarget);
056
057  /**
058   * Register the bean instance into the context.
059   * <p>
060   * Beans are added in an appropriate order to satisfy dependencies.
061   * </p>
062   *
063   * @param bean  The bean instance that has been created.
064   * @param name  The (optional) name of the instance.
065   * @param types Interfaces and class level annotations this bean provides or associates to.
066   */
067  <T> T register(T bean, String name, Class<?>... types);
068
069  /**
070   * Register the bean as a Primary bean.
071   */
072  <T> T registerPrimary(T bean, String name, Class<?>... types);
073
074  /**
075   * Register the bean as a secondary bean.
076   */
077  <T> T registerSecondary(T bean, String name, Class<?>... types);
078
079  /**
080   * Add a lifecycle bean.
081   */
082  void addLifecycle(BeanLifecycle bean);
083
084  /**
085   * Add a field injector.
086   */
087  void addInjector(Consumer<Builder> injector);
088
089  /**
090   * Add a child context.
091   */
092  void addChild(BeanContext context);
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 a dependency.
106   */
107  <T> T get(Class<T> cls);
108
109  /**
110   * Get a named dependency.
111   */
112  <T> T get(Class<T> cls, String name);
113
114  /**
115   * Get a list of dependencies for the interface type .
116   */
117  <T> List<T> getList(Class<T> interfaceType);
118
119  /**
120   * Get a set of dependencies for the interface type .
121   */
122  <T> Set<T> getSet(Class<T> interfaceType);
123
124  /**
125   * Get a candidate dependency allowing it to be null.
126   */
127  <T> BeanEntry<T> candidate(Class<T> cls, String name);
128
129  /**
130   * Build and return the bean context.
131   */
132  BeanContext build();
133
134  /**
135   * Return a potentially enriched bean for registration into the context.
136   * Typically for use with mockito spy.
137   *
138   * @param bean  The bean with dependencies injected
139   * @param types The types this bean registers for
140   * @return Either the bean or the enriched bean to register into the context.
141   */
142  <T> T enrich(T bean, Class<?>[] types);
143}