# 组件标识 Component

> For the complete documentation index, see [llms.txt](https://simbot.forte.love/llms.txt).

组件标识 指的是 `simbot-api` 模块中对外提供的接口类型 `Component`。它的定义大致如下：

```KOTLIN
public interface Component {
    /**
     * 一个组件的ID。
     * 组件id建议使用类似于Java包路径的格式, 
     * 例如 `org.example.Sample` 并尽量避免重复。
     */
    public val id: String

    /**
     * 组件对外提供的统合所有所需的序列化信息。
     * 通常为 message 类型的序列化或文件配置类的序列化信息。
     */
    public val serializersModule: SerializersModule
    
    // 其他省略...
}
```

id
: 此组件的一个唯一ID标识。

serializersModule
: 此组件的各种序列化信息, 例如消息元素、可序列化的 `Bot` 配置类等。

## 使用组件标识

组件标识用于构建 `Application` 的过程中, 先注册组件标识, 用来告知后续步骤将要被注册的 插件 并为它提供一些可能的配置。

首先我们假设有如下这样的一个 `Component` 实现：

```KOTLIN
class FooComponent : Component {
    override val id: String = "example.foo"
    override val serializersModule: SerializersModule = EmptySerializersModule()

    companion object Factory : ComponentFactory<FooComponent, Unit> {
        override val key: ComponentFactory.Key = object : ComponentFactory.Key {}
        override fun create(context: ComponentConfigureContext, configurer: ConfigurerFunction<Unit>): FooComponent {
            return FooComponent()
        }
    }
}
```

### 安装

接下来我们要在 `Application` 中 安装(`install`) 这个假设出来的 `FooComponent`:

Kotlin:

```KOTLIN
launchSimpleApplication {
    install(FooComponent)
}
```

Java:

```JAVA
Applications.launchApplicationAsync(Simple.INSTANCE, configurer -> {
    configurer.install(FooComponent.Factory);
});
```

```JAVA
Applications.launchApplicationBlocking(Simple.INSTANCE, configurer -> {
    configurer.install(FooComponent.Factory);
});
```

### 配置

假如 `FooComponent` 有可配置的信息的话, 也可以使用 DSL/Lambda 对其进行配置:

Kotlin:

```KOTLIN
launchSimpleApplication {
    install(FooComponent) {
        // 配置...
    }
}
```

Java:

```JAVA
Applications.launchApplicationAsync(Simple.INSTANCE, configurer -> {
    configurer.install(FooComponent.Factory, conf -> {
        // 配置...
    });
});
```

```JAVA
Applications.launchApplicationBlocking(Simple.INSTANCE, configurer -> {
    configurer.install(FooComponent.Factory, conf -> {
        // 配置...
    });
});
```

### 事后获取

当我们注册完成、并启动了一个 `Application` 之后, 如果想要获取注册过的组件, 则可以在 `Application` 中找到它们：

Kotlin:

```KOTLIN
val app = launchSimpleApplication {
    install(FooComponent)
}

app.components.forEach { component ->
    // 所有注册了的组件
}
```

Java:

```JAVA
Applications.launchApplicationAsync(Simple.INSTANCE, configurer -> {
    configurer.install(FooComponent.Factory);
}).asFuture().thenAccept(app -> {
    for (var component : app.getComponents()) {
        // 所有注册了的组件...
    }
});
```

```JAVA
var app = Applications.launchApplicationBlocking(Simple.INSTANCE, configurer -> {
    configurer.install(FooComponent.Factory);
});

for (var component : app.getComponents()) {
    // 所有注册了的组件...
}
```

