# Injecting configuration

Tubing provides an annotation which you can use to inject configuration properties in any [Tubing bean](https://staffplusplus-minecraft.gitbook.io/tubing/tubing-core/broken-reference).<br>

### Basic setup

If you only have the default configuration file, called `config.yml` there is no special configuration that you need to do. You can use the [@ConfigProperty](https://staffplusplus-minecraft.gitbook.io/tubing/annotations#configproperty) annotation to inject any property.\
\
For example given following configuration:

```yaml
broadcast-prefix: "[BROADCAST] >> "
cooldown-time: 60
```

#### Option 1: separate configuration bean

```java
@IocBean
public class Configuration {

    @ConfigProperty("broadcast-prefix")
    public String broadcastPrefix;
    @ConfigProperty("cooldown-time")
    public int cooldownTime;
}
```

And inject the Configuration bean where you need it:

```java
@IocBukkitListener
public class GuiBroadcaster implements Listener {


    private final MessageService messageService;
    private final Configuration configuration;

    public GuiBroadcaster(MessageService messageService, Configuration configuration) {
        this.messageService = messageService;
        this.configuration = configuration;
    }

    @EventHandler
    public void handleBroadcastEvent(MessageBroadcastedEvent messageBroadcastedEvent) {
        String message = messageBroadcastedEvent.getBroadcastedMessage().getMessage();
        Bukkit.getOnlinePlayers().forEach(p -> messageService.sendMessage(p, configuration.broadcastPrefix + message));
    }

}
```

#### Option 2: Inject property directly where needed

You don't need to create a special Configuration bean, you can also just inject the configuration property directly into the bean where you need it.

```java
@IocBukkitListener
public class GuiBroadcaster implements Listener {

    @ConfigProperty("tubing-example.broadcast-prefix")
    private String broadcastPrefix;

    private final MessageService messageService;
    
    public GuiBroadcaster(MessageService messageService) {
        this.messageService = messageService;
    }

    @EventHandler
    public void handleBroadcastEvent(MessageBroadcastedEvent messageBroadcastedEvent) {
        String message = messageBroadcastedEvent.getBroadcastedMessage().getMessage();
        Bukkit.getOnlinePlayers().forEach(p -> messageService.sendMessage(p, broadcastPrefix + message));
    }

}
```

### Multiple configuration files

Often with larger plugins you might have multiple configuration files to keep things tidy.

When we do have other configuration files we need to tell plugin the we do have multiple configuration files. This can be done by creating a TubingConfigurationProvider bean.&#x20;

```java
@IocBean
public class ExampleConfigurationProvider implements TubingConfigurationProvider {
    @Override
    public List<ConfigMigrator> getConfigurationMigrators() {
        return Collections.emptyList();
    }

    @Override
    public List<ConfigurationFile> getConfigurationFiles() {
        return Arrays.asList(
            new ConfigurationFile("config.yml"),
            new ConfigurationFile("configuration/databaseConfig.yml", "database")
        );
    }
}
```

In the above example I load in 2 configuration files. One is the default `config.yml` file, the other is a separate configuration file for all database related properties, called `databaseConfig.yml`. The second parameter of the ConfigurationFile constructor is the key of the config file. The **key** is important because this key will be later on used when we want to inject the property.

This is the only thing that you need to do to setup multiple configuration files. When injecting the config property we can use the earlier defined key as prefix.

#### databaseConfig.yml

```yaml
host: 'myhost.com'
port: 3306
username: 'myuser'
password: 'mypass'
database-name: 'tubingexample'
```

```java
@IocBean
public class DatabaseConfiguration {

    @ConfigProperty("database:host")
    public String host;
    @ConfigProperty("database:port")
    public int port;
    @ConfigProperty("database:username")
    public String username;
    @ConfigProperty("database:password")
    public String password;
    @ConfigProperty("database:database-name")
    public String databaseName;
    
}
```

### Configuration transformer

We often have a bit more complex configuration types. The @ConfigProperty annotation can automatically map simple values like Strings, primitive types and enums, and simple lists.\
\
If we need something more complex we can define a transformer. A transformer is a class which will take the value from the FileConfiguration class and transform it into something else. Tubing will inject the result of the transformer into the bean.

Example:

#### Config.yml

```yaml
# comma separated list
tubing-comma-split: yes,no,maybe
```

#### Transformer

The transformer must implement the `IConfigTransformer` interface.\
Basically this is just a mapper. The below example will simple take the value from the config file and split the String value by commas, and return the list.

```java
public class CommaListTransformer implements IConfigTransformer<List<String>, String> {
    @Override
    public List<String> mapConfig(String value) {
        // split the config value by commas
        return Arrays.asList(value.split("\\s*,\\s*"));
    }
}
```

Now we can Inject this list into our bean like this:

```java
@ConfigProperty("tubing-comma-split")
@ConfigTransformer(CommaListTransformer .class)
public List<String> commaSeparatedValues;
```

Tubing will use the transformer and inject the result value

### Configuration placeholders

In Tubing it's possible to reference other properties in your property value by using the {{}} notation.

For example:

```
messages:
    some-prefix: "SomePrefix >>"
    example: "{{messages.some-prefix}} My cool message here" 
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://staffplusplus-minecraft.gitbook.io/tubing/tubing-core/injecting-configuration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
