kotlin-inject icon indicating copy to clipboard operation
kotlin-inject copied to clipboard

Allow to use "fun" as a "builder" of assisted dependency

Open dimsuz opened this issue 2 years ago • 2 comments

It seems that currently only having val lambdas is supported. This doesn't compile:

@Component
abstract class AssistedComponent {
  abstract fun target(arg: String): AssistedTarget
}

@Inject
class AssistedTarget(@Assisted arg: String)

failing with an error:

Class 'InjectAssistedComponent' is not abstract and does not implement 
abstract base class member public abstract fun target(arg: String)

Here's the generated class, which indeed lacks an "override":

public class InjectAssistedComponent() : AssistedComponent()

If I convert fun to val, it works without any problems and the correct code is generated. I.e. this works OK:

@Component
abstract class AssistedComponent {
  abstract val target: (arg: String) -> AssistedTarget
}
  • I understand that README only mentions val, but somehow I expected that fun would've worked too, because it does work for non-assisted cases: I can use val/fun there as I please
  • There are similar looking issues reported, but not quite like this one, close this if it's a duplicate.

dimsuz avatar Apr 25 '23 23:04 dimsuz

Had considered implementing this but not sure it pulls it's weight as a feature, since it would only be for components, you still need the lambda form for anywhere else you'd be injecting it. And if you follow the recomendation of creating a type alias it would look like:

  abstract val target: CreateAssistedTarget

anyway. But maybe it's clear enough what it does to be harmless to have as a feature. Either way, the current error is not good though.

As a side note: fun does work here, though maybe not as you expected:

@Component
abstract class AssistedComponent {
  abstract fun target(): (String) -> AssistedTarget
}

evant avatar Apr 25 '23 23:04 evant

you still need the lambda form for anywhere else you'd be injecting it

Perhaps this could be done automagically: I have fun in component, but whenever lambda is injected, kotlin-inject would derive lambda type from fun-type and properly inject.

But in general I agree that having lambda everywhere might be a simpler and consistent thing to do, if communicated clearly.

dimsuz avatar Apr 26 '23 00:04 dimsuz