001package io.dinject;
002
003/**
004 * Used to explicitly name a bean context and optionally specify if it depends on other bean contexts.
005 * <p>
006 * If this annotation is not present then the name will be derived as the "top level package name"
007 * e.g. "org.example.featuretoggle"
008 * </p>
009 *
010 * <p>
011 * Typically there is a single bean context per Jar (module). In that sense the name is the "module name" and
012 * the dependsOn specifies the names of modules that this depends on (provide beans that are used to wire this module).
013 * </p>
014 *
015 * <p>
016 * This annotation is typically placed on a top level interface or package-info in the module.
017 * </p>
018 *
019 * <pre>{@code
020 *
021 * package org.example.featuretoggle;
022 *
023 * import io.dinject.ContextModule;
024 *
025 * @ContextModule(name = "feature-toggle")
026 * public interface FeatureToggle {
027 *
028 *   boolean isEnabled(String key);
029 * }
030 *
031 * }</pre>
032 *
033 * <h2>dependsOn</h2>
034 * <p>
035 * We specify <code>dependsOn</code> when we have a module that depends on beans that
036 * will be supplied by another module (jar).
037 * </p>
038 * <p>
039 * In the example below we have the "Job System" which depends on the common "Feature Toggle" module.
040 * When wiring the Job system module we expect some beans to be provided by the feature toggle module (jar).
041 * </p>
042 *
043 * <pre>{@code
044 *
045 * package org.example.jobsystem;
046 *
047 * import io.dinject.ContextModule;
048 *
049 * @ContextModule(name = "job-system", dependsOn = {"feature-toggle"})
050 * public interface JobSystem {
051 *
052 *   ...
053 * }
054 *
055 * }</pre>
056 */
057public @interface ContextModule {
058
059  /**
060   * The name of this context/module.
061   * <p>
062   * Other modules can then depend on this name and when they do they should wire after than module.
063   * </p>
064   */
065  String name() default "";
066
067  /**
068   * Additional module features that is provided by this module.
069   * <p>
070   * These names are an addition to the module name and can be used in the <code>dependsOn</code> of other modules.
071   * </p>
072   *
073   * <pre>{@code
074   *
075   * // A module that provides 'email-service' and also 'health-check'.
076   * // ie. it has bean(s) that implement a health check interface
077   * @ContextModule(name="email-service", provides={"health-checks"})
078   *
079   * // provides beans that implement a health check interface
080   * // ... wires after 'email-service'
081   * @ContextModule(name="main", provides={"health-checks"}, dependsOn={"email-service"})
082   *
083   * // wire this after all modules that provide 'health-checks'
084   * @ContextModule(name="health-check-service", dependsOn={"health-checks"})
085   *
086   * }</pre>
087   */
088  String[] provides() default {};
089
090  /**
091   * The list of modules this context depends on.
092   * <p>
093   * Effectively dependsOn specifies the modules that must wire before this module.
094   * </p>
095   * <pre>{@code
096   *
097   * // wire after a module that is called 'email-service'
098   * // ... or any module that provides 'email-service'
099   *
100   * @ContextModule(name="...", dependsOn={"email-service"})
101   *
102   * }</pre>
103   */
104  String[] dependsOn() default {};
105
106}