ConversionService

ConversionService は、ある値を別の型の値に変えます。たとえば設定ファイルのテキスト '10s' を Duration にします。

使う理由

フレームワークは型付きの値を埋めるたびに変換サービスを呼びます。@Value の注入、PropertyResolver.getPropertyAs<T>、@ConfigurationProperties のバインドです。DefaultConversionService は一般的な型をすでに知っているため、ほとんどのアプリケーションは結果を受け取るだけです。

自分で使うのは次の 2 つの場合です。

自分のコードで値を変換するときも convert<T> を直接呼びます。

DefaultConversionService に組み込まれている変換:

例

import 'package:spring_core_dart/spring_core_dart.dart';

/// 金額。設定ファイルでは `12.50 EUR` と書く。
class Money {
  const Money(this.amount, this.currency);

  final double amount;
  final String currency;

  static Money parse(String text) {
    final [amount, currency] = text.trim().split(' ');
    return Money(double.parse(amount), currency);
  }
}

enum Level { info, warn, error }

@Configuration()
class ConversionConfig {
  // コンテキストはこの Bean で @Value の引数を変換するので、
  // `@Value(r'${shop.min-order}') Money minOrder` が使える。
  @Bean()
  ConversionService conversionService() => DefaultConversionService()
    ..addConverter<String, Money>(Money.parse)
    ..addCollectionConverters<Money>() // List<Money> と Set<Money>
    ..addEnum(Level.values); // `warn`、`WARN`、`Warn` のどれでも一致する
}

@Service()
class Checkout {
  Checkout(
    @Value(r'${shop.min-order:10.00 EUR}') this.minOrder,
    @Value(r'${shop.alert-level:warn}') this.alertLevel,
  );

  final Money minOrder;
  final Level alertLevel;
}

コードでの変換:

final service = DefaultConversionService();
service.convert<int>('0x1F'); // 31
service.convert<bool>('yes'); // true
service.convert<List<int>>('1, 2, 3'); // [1, 2, 3]
service.convert<int?>(''); // null
service.convert<String>(const Duration(seconds: 10)); // 'PT10S'

エラー:

メンバー

ConversionService:

名前 戻り値 意味
convert<T>(source) T T に変換する。すでに T ならそのまま返す。
convertTo(source, targetType) Object? 実行時に Type 値としてだけ分かる型に変換する。
canConvert(source, targetType) bool この値を受け付けるコンバーターがあるか。値が解析できるかは確認しない。
canConvertType<S>(targetType) bool 値がまだない段階で、型 S の値を変換できるか。

ConverterRegistry(GenericConversionService と DefaultConversionService が実装):

名前 意味
addConverter<S, T>(converter) S から T ちょうどへの関数を追加する(T? にも使われる)。同じ型への後の登録が優先される。
addEnum<E>(values) enum を String との間で、また List<E> / Set<E> として変換できるようにする。名前は大文字小文字と区切り文字を無視して照合する。
addCollectionConverters<E>() List<E> と Set<E> を変換できるようにする。
addMapConverters<K, V>() 任意の Map から Map<K, V> に変換できるようにする。
removeConvertible<T>() T と T? を対象とするコンバーターをすべて削除する。

DefaultConversionService.sharedInstance は、サービスを与えられていないものすべてが使います。これにコンバーターを追加せず、自分のインスタンスを作ってください。

Spring (Java) との対応

@Bean
ConversionService conversionService() {
  DefaultConversionService service = new DefaultConversionService();
  service.addConverter(String.class, Money.class, Money::parse);
  return service;
}

Integer port = service.convert("8080", Integer.class);

重要な違い:

関連項目