While building a lightweight microservices platform, we need an IoC service to bind implementations to interfaces. Given light-4j has server startup and shutdown hooks, we usually only need to inject with a constructor injection during the server startup.
We have evaluated several IoC containers and found them to be too heavy for my use cases. Also, most of them are still using XML as configuration or annotations which eliminate the benefit of configurable IoC.
There are three different injection patterns:
In my opinion, both Field and Setter injections are bad, and the only way injection should be used is the instructor injection. Numeric articles are talking about the pros and cons of each pattern.
Given the above reasons, we have built our own IoC service module which is a lightweight and fast dependency injection framework without any third party dependencies. It only supports constructor inject, and the injection is done during server startup. All the objects are saved into a map, and the key is the interface class name. It can guarantee that only one instance of implementation is available during runtime.
Light encourages developers to build microservices with the Functional Programming Style. One of the fundamental principles is immutability so that the code can be optimized to take advantage of multi-core CPUs. All singleton classes should be designed as immutable, and the initialized object will be cached in the service map ready to be looked up.
Unlike other IoC containers, our service module only deals with singletons during server startup with constructor injection. It gives developers an opportunity to choose from several implementations of an interface in the service.yml config file.
For example, if you have an interface with two different implementations, you can change the externalized service.yml file on production to switch between two implementations.
The following is an example of service.yml in the test folder for this module.
Please note that the sequence of binding in the config file is crucial. If one implementation uses another injected object, that object must be defined in the configuration first.
The service module is one of the most important modules in Light and a lot of other components are relying on it. To help developers to learn it quickly, we have provided a service tutorial in the tutorial section.