> For the complete documentation index, see [llms.txt](https://divine.qibergames.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://divine.qibergames.com/advanced-usage/markdown.md).

# Service factories

When requesting dependencies, the implementations may differ for various contexts. DiVine lets you specify factories, which have the purpose of creating instances based on the given parameters.

<figure><img src="/files/8eiPjQPaOhSW5qapzPXU" alt=""><figcaption></figcaption></figure>

You can bind a factory for a service directly.

```java
@Service(factory = MyFactory.class)
class MyService { ... }
```

You can define your factory somewhere.

```java
class MyFactory implements Factory<MyService, MyProperty> { ... }
```

The factory properties may differ depending on your use case.

```java
class MyFactory implements Factory<MyService, String> { ... }
```

```java
class MyFactory implements Factory<MyService, MyEnum> { ... }
```

... and so on.

When requesting a dependency for a service, you must also pass in the properties, as specified by the service.

```java
@Service(factory = CoolFactory.class)
interface AmazingService { ... }
```

```java
class CoolFactory implements Factory<AmazingService, String> { ... }
```

```java
void requestDependency() {
    AmazingService service = Container.get(AmazingService, "EXAMPLE_PARAMETER");
}
```

{% hint style="info" %}
Note that parameter arguments are checked at runtime, so factory types are guaranteed inside the factory class.
{% endhint %}

The following code showcases a simple way of requesting different implementations for a service.

```java
@Service(
    // use the `CarFactory` class to create new instances for the `Car` type
    factory = CarFactory.class,
    // use `TRANSIENT` scope, to create a new car instance, each time a car 
    // is requested
    scope = ServiceScope.TRANSIENT 
)
interface Car {
    void drive();
}

enum CarType {
    MERCEDES,
    BMW,
    FERRARI
}

class CarFactory implements Factory<
    Car, 
    CarType // you may specify any arbitrary factoryparameter type
> {
    @Override
    public @NotNull Car create(
        @NotNull Service descriptor, @NotNull Class<? extends Car> type, 
        @NotNull Class<?> context, @Nullable CarType carType
    ) {
        return switch (carType) {
            case MERCEDES -> new MercedesCar();
            case BMW -> new BMWCar();
            case FERRARI -> new FerrariCar();
        };
    }
}

@Service
class CarDealership() {
    public Car orderCar(CarType type) {
        return Container.get(Car.class, type);
    }
}

void orderCars() {
    CarDealership dealership = Container.get(CarDealership.class);
    assert dealership.orderCar(CarType.MERCEDES) instanceof MercedesCar;
    assert dealership.orderCar(CarType.BMW) instanceof BMWCar;
    assert dealership.orderCar(CarType.FERRARY) instanceof FerraryCar;
}
```
