mcarleio / konvert

This kotlin compiler plugin is using KSP API and generates kotlin code to map one class to another
https://mcarleio.github.io/konvert/
Apache License 2.0
93 stars 8 forks source link

Allow Spring/CDI injection #1

Closed tokazio closed 1 year ago

tokazio commented 1 year ago

Using @Konverter

The mapper implementation would be annotated with @Component / @ApplicationScope to allow Spring/CDI injection

@Konverter could have a parameter to select from Spring or cdi

mcarleio commented 1 year ago

Thank you for the idea. I know that MapStruct offers this functionality.

  1. Generating Spring/CDI annotations

I am not sure about the priority of this feature, especially as Spring and CDI offer simple ways to dynamically register beans (e.g. @Bean and @Provides).

Also, Konvert should not be coupled too tight with any framework and I am thinking about if this could also be an extension (like konvert-spring) to have a clean processor. But of course this would be more complex.

  1. Having configuration via annotation

Adding a configuration annotation (like MapStruct offers) is at least planned. But due to the lack of configurations (only one at the moment), it probably does not have high prio as well.

jakoss commented 1 year ago

I'd love that feature too

@mcarleio I did something very similar to this in other mapper: https://github.com/s0nicyouth/kmapper/pull/10

I think i could to PR with integration of koin/anvil/hilt (i do not know about Spring, since i mostly focus on android development). As to extension - i don't think that's possible, since you have to apply the annotations directly on class generated by the main processor, but i don't think this is really "tight coupling" since you do not directly depend on injection frameworks. You just apply annotations via ClassName. You can add new module for annotations that are related to injection framework. So let's say you want to create a mapper that's injected via koin. You can annotate your interface like this:

@Konvert
@KoinSingle
interface YourMapper { }

In this case @KoinSingle would live in a separate module, but the implementation of processor would have to stay in main module

mcarleio commented 1 year ago

You are right, it is not directly "tight coupling", but imagine how the processor will look like, if you add special logic for each existing DI framework. I have a rough idea, how this could be done, but I have to test it out and see, if this works well (and feels good). I will comment again, when I have more than a rough plan. As I have only little expierence with Koin and co. I would be happy if you then create a PR 👍

jakoss commented 1 year ago

The processor itself can be modularized to separate concerns, i just don't think exposing it as separate artifacts is feasible (since i don't think two separate processors can cooperate). But waiting for results of your tests :)

Vaguely related to this thread - maybe you should expose ksp option to generate classes instead of objects? For injection that seems like a better fit. I can imagine that you don't always want to keep the mapper in memory, since some mappers but be used once in a month for some rare scenarios

mcarleio commented 1 year ago

@jakoss please have a look onto #3. Do you think this is sufficient, or are you missing stuff?

jakoss commented 1 year ago

@mcarleio Looks great, i'll look at adding koin to this mix in some spare time :)

mcarleio commented 1 year ago

Done with #3