> For the complete documentation index, see [llms.txt](https://docs.etdon.com/commons/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.etdon.com/commons/components/dependency-injection.md).

# Dependency Injection

com.etdon.commons.di

In order to assist with dependency injection the library features a `ServiceProvider` concept that can manage the registration and obtaining of services for you. The library features one implementation by default in the form of the `InstanceServiceProvider` which manages services on a registered instance level.\
\
In order to create a new `InstanceServiceProvider` you should use the fluent builder accessible through the `#builder` static factory method contained in the same class:

```java
final ServiceProvider serviceProvider = 
            InstanceServiceProvider.builder()
                        .service(new ExampleService())
                        .selfService()
                        .build();
```

As shown in the code snippet services can be pre-registered during the building process, however, you can also register them later utilizing the `ServiceProvider#register` method and its overloads. The `#selfService` method instructs the `ServiceProvider` to register itself to its own registry, if this is not something you need you can simply remove the call.

In order to obtain a service from a `ServiceProvider` you can either use the `#get` or `#getOrThrow` (including overloads) method:

```java
final ExampleService exampleService = serviceProvider.get(ExampleService.class);
```

The `#get` and `#getOrThrow` methods function similarly however the return value of the former is `Nullable` while the latter will throw an exception if the service is not present in the registry making it `NotNull`.

In order to check if a certain services is present in the registry the `#has` method (including overloads) can be used:

```java
final boolean hasService = serviceProvider.has(ExampleService.class);
```

***

In some situations multiple services of the same type might be needed:

```java
final ExampleService importantService = new ExampleService();
final ExampleService otherImportantService = new ExampleService();
```

For situations like this a string identifier can be provided during the registration and other actions to distinguish between said services. The library internally creates a `ServiceIdentifier` instance for all services wherever or not they have a string identifier to ensure proper identification.

```java
serviceProvider.register("important", importantService);
serviceProvider.register("otherImportant", otherImportantService);

serviceProvider.has(ExampleService.class, "important");
serviceProvider.has(ExampleService.class, "otherImportant");

serviceProvider.get(ExampleService.class, "important");
serviceProvider.get(ExampleService.class, "otherImportant");
```
