Как обработать конфигурацию плагина JSON со структурами, не известными во время компиляции - PullRequest
0 голосов
/ 07 ноября 2019

Я работаю с программным обеспечением Go, которое позволяет использовать несколько плагинов.

  • Плагин нельзя использовать дважды (по выбору) => плагин либо включен, либо отключен
  • Имена плагинов уникальны
  • Все плагины настроены на специфичную для плагина конфигурацию, определенную как JSON-serializable struct

Использование плагинов контролируется с помощью одной конфигурации,Рассмотрим следующий упрощенный пример структуры конфигурации:

type PluginConfig struct {
    PluginA *PluginA `json:"pluginA,omitEmpty"`
    PluginB *PluginB `json:"pluginB,omitEmpty"`
    PluginC *PluginC `json:"pluginC,omitEmpty"`
    PluginD *PluginD `json:"pluginD,omitEmpty"`
}

Где-то в коде проверено каждое из полей и добавлен фактический плагин, если была предоставлена ​​конфигурация:

if config.PluginA != nil {
    AddPlugin(plugina.New(config.PluginA))
}
if config.PluginB != nil {
    AddPlugin(pluginb.New(config.PluginB))
}
// ...

Я пытаюсь переработать программное обеспечение, чтобы внешние плагины также поддерживали. Программное обеспечение должно функционировать как прежде, поэтому формат и способ настройки не могут быть изменены. Кроме того, мне необходимо использовать пакет encoding/json по умолчанию для демонтажа конфигурации.

Если бы я знал все плагины во время компиляции, я мог бы go generate код конфигурацииstruct перед компиляцией, а также сгенерируйте соответствующие операторы if config.SomePlugin { }. Хотя это может даже иметь хорошую производительность, потому что динамический поиск не используется, я все равно буду ограничен знанием всех плагинов заранее. Если бы это было так, согласитесь ли вы с тем, что этот подход является верным путем?

Что я мог бы сделать, если бы мог получить список плагинов только во время выполнения? Как я мог обработать файл конфигурации тогда, чтобы не только имена плагинов были динамическими, но я также не знал бы о конкретной конфигурации раньше?

1 Ответ

3 голосов
/ 07 ноября 2019

У вас есть два варианта:

  1. Unmarshal для универсального типа, такого как map[string]interface{}
  2. Unmarshal to json.RawMessage

В любом случаезатем вы можете передать эти данные плагину, как только он будет загружен, чтобы выполнить полное демаршалинг / преобразование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...