2626import java .nio .file .Path ;
2727import java .nio .file .Paths ;
2828import java .util .ArrayList ;
29+ import java .util .HashMap ;
2930import java .util .Iterator ;
3031import java .util .LinkedList ;
3132import java .util .List ;
33+ import java .util .Map ;
34+ import java .util .Optional ;
3235import java .util .ServiceLoader ;
3336import java .util .concurrent .Executor ;
3437import java .util .function .Consumer ;
@@ -52,6 +55,8 @@ public class Jooby implements Router {
5255
5356 private LinkedList <Throwing .Runnable > stopCallbacks ;
5457
58+ private Map <Object , Object > services = new HashMap <>();
59+
5560 /**
5661 * Not ideal but useful. We want to have access to environment properties from instance
5762 * initializer. So external method before creating a new Jooby instance does a call to
@@ -169,7 +174,7 @@ public Jooby renderer(@Nonnull String contentType, @Nonnull Renderer renderer) {
169174 }
170175
171176 @ Nonnull public Jooby install (@ Nonnull Extension extension ) {
172- extension .install (environment , this );
177+ extension .install (this );
173178 return this ;
174179 }
175180
@@ -252,6 +257,52 @@ public Jooby mode(ExecutionMode mode) {
252257 return this ;
253258 }
254259
260+ public <T > T require (Class <T > type ) {
261+ return findService (type , type .getName ());
262+ }
263+
264+ public <T > T require (Class <T > type , String name ) {
265+ return findService (type , type .getName () + "." + name );
266+ }
267+
268+ private <T > T findService (Class <T > type , String key ) {
269+ Object service = services .get (key );
270+ if (service == null ) {
271+ throw new IllegalStateException ("Service not found: " + type );
272+ }
273+ return type .cast (service );
274+ }
275+
276+ public <T > Jooby addService (@ Nonnull Class <T > type , @ Nonnull T service ) {
277+ putService (type , null , service );
278+ return this ;
279+ }
280+
281+ public <T > Jooby addService (@ Nonnull T service ) {
282+ putService (service .getClass (), null , service );
283+ return this ;
284+ }
285+
286+ public <T > Jooby addService (@ Nonnull String name , @ Nonnull T service ) {
287+ putService (service .getClass (), name , service );
288+ return this ;
289+ }
290+
291+ public <T > Jooby addService (@ Nonnull Class <T > type , @ Nonnull String name , @ Nonnull T service ) {
292+ putService (type , name , service );
293+ return this ;
294+ }
295+
296+ private void putService (@ Nonnull Class type , String name , @ Nonnull Object service ) {
297+ String defkey = type .getName ();
298+ String key = type .getName ();
299+ if (name != null ) {
300+ key += "." + name ;
301+ }
302+ services .put (key , service );
303+ services .putIfAbsent (defkey , service );
304+ }
305+
255306 /** Boot: */
256307 public Server start () {
257308 List <Server > servers = ServiceLoader .load (Server .class ).stream ()
0 commit comments