ansman/auto-dagger

Feature Suggestion: Add support for auto binding for third party libraries

Closed this issue · 11 comments

I think that it would be amazing if this library (perhaps via non-core additional modules) could support autobinding various, well known libraries commonly used.

I had two in mind specifically here:

  • Retrofit: i currently have to always remember to create a binding for the retrofit routes i create and I always forget. Having an annotation that can be added to the retrofit interface itself would save a lot of duplication

  • Sqldelight: I ALWAYS forget to add new XXXQueries classes that are created when i create a new table, to the dependency graph. Having a tool autobind all the existing Queries classes would save so much effort

ansman commented

That sounds like a great idea!

When it comes to retrofit, we could automatically find your retrofit services and provide them into the graph given that there is a Retrofit instance in the graph. We could even support multiple instance using qualifiers.

SQLDelight seems trickier since the source of truth is the .sq files. To make matters worse, you cannot infer the table name from the filename. If we could somehow inject an annotation to the Database class this would be trivial.

Couldn't it scan for the generated Queries classes? They all end in that suffix and take a SqlDriver as the first constructor parameter

Or alternatively we could somehow autofind the Database instance as it contains all generated Queries classes that need to be injected as its fields (you can see the Module class that this feature would get rid of for my project here: https://github.com/savvasdalkitsis/uhuruphotos-android/blob/main/feature/db/domain/implementation/src/main/kotlin/com/savvasdalkitsis/uhuruphotos/feature/db/domain/implementation/DbModule.kt). As you can see, all i'm doing is providing all the fields in the Database class

Ah i just noticed that you already suggested the second part of my suggestion above.

The Database class is always generated in the module that has the sqdelight plugin using the module packagename.Database namespace.

Maybe that could the way to discover the class?

While we're at it, autobinding the Database class itself would be fantastic. Sqldelight 2.x introduced the need to inject column adapters for columns that are mapped to kotlin types and it's very verbose at the moment as you can see form the link i shared above :(

ansman commented

Yeah, I suppose that if the database class would be figured out it would be fine. The issue is that a classic Java Annotation Processor needs an annotation to scan for. You can't really just generate arbitrary code based on any input file. With KSP it's possible but until Dagger/Hilt uses KSP it will be very hard to make it work as it will require a bunch of specialized setup.

It will also be hard to automatically provide the database as AutoDagger wouldn't know how to create the adapters. It would be possible if you used @AutoBind on the adapters however.

If we could get SQLDelight to allow adding annotations to the generated database then this would become much much easier.

ansman commented

@burntcookie90 This is similar to how its currently being implemented. So far the compiler artifact is able to handle all integrations but they are provided as separate artifacts se.ansman.dagger.auto:retrofit and se.ansman.dagger.auto:androidx-viewmodel

ansman commented

I am considering changing the artifact coordinates to clearly indicate they are extensions but would love to hear thoughts on this.

Honestly, I think its ok the way it is. The only confusion was that it wasn't clearly announced in the release notes here https://github.com/ansman/auto-dagger/releases/tag/0.7.0 (but thats on me for not clicking through to the docs link).

@ansman bit of a stretch, since it's not very popular yet, but do you reckon it would be easy to add ktorfit support to @AutoBindService?

@savvasdalkitsis Done: https://github.com/ansman/auto-dagger/pull/153/files
Please take a look when you get a chance.