# Object Suppliers

Due to the fact that ShapeShift uses reflection behind the scenes, destination **classes need a no arg constructor**. But in some cases you have no control over the destination classes and cannot modify them to add a no arg constructor. This is where Object Suppliers comes into play, you can register object suppliers to the ShapeShift instance to add your own logic for instance generation.

{% hint style="info" %}
[Instance Mapping](https://shapeshift.krud.dev/guides/instance-mapping) is another solution for the no arg constructor issue. The advantage of Object Suppliers is that they also work when mapping classes containing subclasses while Instance Mapping only solves the issue for the top level class instance.
{% endhint %}

We have two classes, the source class `SimpleEntity` and the destination class `SimpleEntityDisplay`.&#x20;

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
@DefaultMappingTarget(SimpleEntityDisplay::class)
data class SimpleEntity(
    @MappedField
    val name: String,
    @MappedField
    val description: String,
    val privateData: String
)
```

{% endtab %}

{% tab title="Java" %}

```java
@DefaultMappingTarget(SimpleEntityDisplay.class)
public class SimpleEntity {
    @MappedField
    private String name;
    @MappedField
    private String description;
    private String privateData;
    // Getters and Setters...
}
```

{% endtab %}
{% endtabs %}

The destination class does not have a no arg constructor.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
data class SimpleEntityDisplay(
    val name: String,
    val description: String
)
```

{% endtab %}

{% tab title="Java" %}

```java
public class SimpleEntityDisplay {
    private String name;
    private String description;

    public SimpleEntityDisplay(String name, String description) {
        this.name = name;
        this.description = description;
    }
    // Getters and Setters...
}
```

{% endtab %}
{% endtabs %}

To solve this issue we need to either use [instance mapping](https://shapeshift.krud.dev/guides/instance-mapping) or add an object supplier for the class.

## Adding Object Suppliers

Adding object suppliers is available through the `ShapeShiftBuilder` class. Object suppliers can be added inline or as a separate class.

### Class Object Suppliers

To create an object supplier class implement the `Supplier` interface.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
class SimpleEntityDisplaySupplier : Supplier<SimpleEntityDisplay> {
    override fun get(): SimpleEntityDisplay {
        return SimpleEntityDisplay("", "")
    }
}
```

{% endtab %}

{% tab title="Java" %}

```java
public class SimpleEntityDisplaySupplier implements Supplier<SimpleEntityDisplay> {
    @Override
    public SimpleEntityDisplay get() {
        return new SimpleEntityDisplay("", "");
    }
}
```

{% endtab %}
{% endtabs %}

And register it to the `ShapeShift` instance.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
val shapeShift = ShapeShiftBuilder()
    .withObjectSupplier(SimpleEntityDisplaySupplier())
    .build()
```

{% endtab %}

{% tab title="Java" %}

```java
ShapeShift shapeShift = new ShapeShiftBuilder()
        .withObjectSupplier(new SimpleEntityDisplaySupplier(), SimpleEntityDisplay.class)
        .build();
```

{% endtab %}
{% endtabs %}

### Inline Object Suppliers

It is also possible to add the object supplier logic inline.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
val shapeShift = ShapeShiftBuilder()
    .withObjectSupplier { SimpleEntityDisplay("", "") }
    .build()
```

{% endtab %}

{% tab title="Java" %}

```java
ShapeShift shapeShift = new ShapeShiftBuilder()
        .withObjectSupplier(() -> new SimpleEntityDisplay("", ""), SimpleEntityDisplay.class)
        .build();
```

{% endtab %}
{% endtabs %}

## Mapping with Object Suppliers

Now that we added an object supplier for the `SimpleEntityDisplay` class we can map to it as if it has a no arg constructor.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
val simpleEntity = SimpleEntity("test", "test description", "private data")
val simpleEntityDisplay = SimpleEntityDisplay("", "")
val result = shapeShift.map<SimpleEntityDisplay>(simpleEntity)
```

{% endtab %}

{% tab title="Java" %}

```java
SimpleEntity simpleEntity = new SimpleEntity();
simpleEntity.setName("test");
simpleEntity.setDescription("test description");
simpleEntity.setPrivateData("private data");
SimpleEntityDisplay result = shapeShift.map(simpleEntity, SimpleEntityDisplay.class);
```

{% endtab %}
{% endtabs %}
