DDD の本を読んだりして、いろいろ class 化して表すのだ、という意識が出てきたり出てこなかったりして、Id となる文字列や数値を class 化しようと誰もが思うはず(要出典)。
その時に、良かれと思って value class を検討していくだろう。
@JvmInline value class MyId(val value: Long)
2025/02/01 現在は Dagger / Hilt でこれを inject しようとしてもできない。
例えば ViewModel に inject して、この MyId
を UseCase や Repository に渡すのだ、と思ってもコンパイルエラーになります。
@HiltViewModel(assistedFactory = MyViewModel.Factory::class) class MyViewModel @AssistedInject constructor( @Assisted private val myId: MyId, private val repository: Repository, ) : ViewModel() { @AssistedFactory interface Factory { fun create(myId: MyId): MyViewModel } init { repository.getData(myId) } ...
[ksp] java.lang.IllegalArgumentException: not a valid name: create-OUFw_og at com.squareup.javapoet.Util.checkArgument(Util.java:53) at com.squareup.javapoet.MethodSpec$Builder.setName(MethodSpec.java:315) at com.squareup.javapoet.MethodSpec$Builder.<init>(MethodSpec.java:310) at com.squareup.javapoet.MethodSpec$Builder.<init>(MethodSpec.java:294) at com.squareup.javapoet.MethodSpec.methodBuilder(MethodSpec.java:188)
じゃあ ViewModel に渡すときはどうするかというと、value class の中身を取り出して inject するか、value class をラップした class を作成するしかない。 例えば value class の中身を取り出してやるとこんな感じか。
@HiltViewModel(assistedFactory = MyViewModel.Factory::class) class MyViewModel @AssistedInject constructor( @Assisted myId: Long, private val repository: Repository, ) : ViewModel() { @AssistedFactory interface Factory { fun create(myId: Long): MyViewModel } private val myId: MyId = MyId(myId) init { repository.getData(myId) } ...
悲しい感じがする。