001package io.avaje.inject.spi; 002 003import io.avaje.inject.BeanContext; 004import io.avaje.inject.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 * Create the root level Builder. 018 * 019 * @param suppliedBeans The list of beans (typically test doubles) supplied when building the context. 020 * @param enrichBeans The list of classes we want to have with mockito spy enhancement 021 */ 022 @SuppressWarnings("rawtypes") 023 static Builder newRootBuilder(List<SuppliedBean> suppliedBeans, List<EnrichBean> enrichBeans) { 024 if (suppliedBeans.isEmpty() && enrichBeans.isEmpty()) { 025 // simple case, no mocks or spies 026 return new DBuilder(); 027 } 028 return new DBuilderExtn(suppliedBeans, enrichBeans); 029 } 030 031 /** 032 * Create a Builder for the named context (module). 033 * 034 * @param name the name of the module / bean context 035 * @param provides the module features this module provides 036 * @param dependsOn the names of modules this module is depends on. 037 */ 038 static Builder newBuilder(String name, String[] provides, String[] dependsOn) { 039 return new DBuilder(name, provides, dependsOn); 040 } 041 042 /** 043 * Return the name of the (module) context this builder is creating. 044 */ 045 String getName(); 046 047 /** 048 * Return the names of module features that this module provides. 049 */ 050 String[] getProvides(); 051 052 /** 053 * Return the names of modules that this module depends on. 054 */ 055 String[] getDependsOn(); 056 057 /** 058 * Set a parent builder that can provide cross-module dependencies. 059 */ 060 void setParent(Builder parent); 061 062 /** 063 * Return true if the bean should be created and registered with the context. 064 * <p/> 065 * Returning false means there has been a (test double) bean already registered and 066 * that we should skip the creation and registration for this bean. 067 * 068 * @param addForType The interface that the bean implements and provides 069 * @param injectTarget The actual bean type we are looking to create and register 070 */ 071 boolean isAddBeanFor(Class<?> addForType, Class<?> injectTarget); 072 073 /** 074 * Return true if the bean should be created and registered with the context. 075 * <p/> 076 * Returning false means there has been a (test double) bean already registered and 077 * that we should skip the creation and registration for this bean. 078 * 079 * @param injectTarget The actual bean type we are looking to create and register 080 */ 081 boolean isAddBeanFor(Class<?> injectTarget); 082 083 /** 084 * Register the bean instance into the context. 085 * <p> 086 * Beans are added in an appropriate order to satisfy dependencies. 087 * </p> 088 * 089 * @param bean The bean instance that has been created. 090 * @param name The (optional) name of the instance. 091 * @param types Interfaces and class level annotations this bean provides or associates to. 092 */ 093 <T> T register(T bean, String name, Class<?>... types); 094 095 /** 096 * Register the bean as a Primary bean. 097 */ 098 <T> T registerPrimary(T bean, String name, Class<?>... types); 099 100 /** 101 * Register the bean as a secondary bean. 102 */ 103 <T> T registerSecondary(T bean, String name, Class<?>... types); 104 105 /** 106 * Add a lifecycle bean. 107 */ 108 void addLifecycle(BeanLifecycle bean); 109 110 /** 111 * Add field and method injection. 112 */ 113 void addInjector(Consumer<Builder> injector); 114 115 /** 116 * Add a child context. 117 */ 118 void addChild(BeanContextFactory factory); 119 120 /** 121 * Get an optional dependency. 122 */ 123 <T> Optional<T> getOptional(Class<T> cls); 124 125 /** 126 * Get an optional named dependency. 127 */ 128 <T> Optional<T> getOptional(Class<T> cls, String name); 129 130 /** 131 * Get a dependency. 132 */ 133 <T> T get(Class<T> cls); 134 135 /** 136 * Get a named dependency. 137 */ 138 <T> T get(Class<T> cls, String name); 139 140 /** 141 * Get a list of dependencies for the interface type . 142 */ 143 <T> List<T> getList(Class<T> interfaceType); 144 145 /** 146 * Get a set of dependencies for the interface type . 147 */ 148 <T> Set<T> getSet(Class<T> interfaceType); 149 150 /** 151 * Get a candidate dependency allowing it to be null. 152 */ 153 <T> BeanEntry<T> candidate(Class<T> cls, String name); 154 155 /** 156 * Return a potentially enriched bean for registration into the context. 157 * Typically for use with mockito spy. 158 * 159 * @param bean The bean with dependencies injected 160 * @param types The types this bean registers for 161 * @return Either the bean or the enriched bean to register into the context. 162 */ 163 <T> T enrich(T bean, Class<?>[] types); 164 165 /** 166 * Build and return the bean context. 167 */ 168 BeanContext build(); 169}