evant / kotlin-inject

Dependency injection lib for kotlin
Apache License 2.0
1.14k stars 51 forks source link

Improve documentation to better understand how to use kotlin-inject #389

Open cybercoder-naj opened 1 month ago

cybercoder-naj commented 1 month ago

This issue may be subjective and not well-phrased, but I'll try my best areas that are confusing that we can perhaps work on to improve.

  1. Not beginner-friendly - I have used Dagger Hilt in the past but not extensively. Coming from that background, I chose kotlin-inject over koin or kodein. However, going over the documentation, it was quite difficult understanding the basic concepts of implementing dependency injection in my project.
  2. Better multiplatform support - With Compose Multiplatform, there is a separate UI Module composeApp/ and a business logic module shared/ but it is not clear what dependencies should be added in each for kotlin-inject to work properly (more on that below).
  3. Provide real-world examples - Going over the text, I personally feel like the documentation is designed for people who understand the library to an extent, not for an end-user who simply wishes to use this library (somewhat tied to beginner-friendly point).

I am building a Compose multiplatform application where composeApp/ module has a ViewModel where I wish to inject a repository. The repository and its dependencies live in shared/ module but I am unable to do so. The create function is an unresolved reference in Component::class.create().repository which is confusing.

Here is a reproduction:

// in shared/src/commonMain/kotlin

@Component
abstract class Component {
  @Provides
  fun provideHttpClient(): HttpClient { // from ktor-client
    return HttpClient {/* config */}
  }

  @Provides
  @Inject
  fun provideRepository(client: HttpClient): Repository {
    return RepositoryImpl(client)
  }
}

// where (for context)
// HttpClient is from ktor-client dependency; and

interface Repository {/* functions */}

class RepositoryImpl(private val httpClient: HttpClient) : Repository

Again, I thought this is how you do it (since that's how Dagger Hilt did it) but I can't test if it works since the create function, Component::class.create() does not exist.

evant commented 4 weeks ago

Thanks for the feedback!

I have used Dagger Hilt in the past but not extensively. However, going over the documentation, it was quite difficult understanding the basic concepts of implementing dependency injection in my project. ... I personally feel like the documentation is designed for people who understand the library to an extent, not for an end-user who simply wishes to use this library

Admittedly sorta yeah. Or more specifically I do feel it's written from the perspective of someone how understands base dagger well (not hilt) and wants to get running with something similar. Sounds like a good idea to make the main docs more beginner-friendly and maybe move some things to a 'dagger' vs 'kotlin-inject' page or something.

Better multiplatform support

There's work being done here! Have you taken a look at https://github.com/evant/kotlin-inject/blob/main/docs/multiplatform.md? The release that includes an annotation to make it more friendly hasn't been released yet (it's only in a SNAPSHOT version) but I'm open to feedback on how to improve anything there.

Would also recommend looking at our sample repo with actual projects set up. Hope this helps!

oblakr24 commented 4 weeks ago

I would mirror the OP's comment; when I integrated it into a fresh KMP project the provided documentation was a bit out of date and inaccurate (I had issues getting the component autogenerated), so I needed a few workarounds by checking other sample projects. (Alas I forgot exactly the steps I did at the time, otherwise I would have listed them here)

Would be good to have a documentation starting from KMP by default (and build.gradle.kts in Kotlin) as I imagine most new users of this library will be KMP projects.

As far as the feedback in improvements is concerned: I am not an experienced library publisher, but I would say:

cybercoder-naj commented 3 weeks ago

Sorry for the inactivity.

maybe move some things to a 'dagger' vs 'kotlin-inject' page or something.

@evant A "versus" page may not be the best but a migration page from dagger/hilt/koin/kodein-di to kotlin-inject is probably something that could be useful. When going through the docs again, I felt the information was going back and forth because code snippets and explanation which can be improved. Assuming that a user has no background in DI, it's probably good to start with a basic "What is a binding" and "binding vs providers" introduction and show the minimal code to achieve that.

Have you taken a look at [multiplatform docs]?

Yes i did indeed, but with ksp being slightly unstable for kmp, I did not have time to experiment with it, since my college project deadline is tight.

Would also recommend looking at our sample repo

That's interesting. I see that it is at the bottom part of the readme documentation. I was overwhelmed looking at the current material that I didn't scroll down to realise there was a link to a sample repo. Possibly migrate a beginner-friendly guide to a website or github pages or github wiki so that the actual git readme is less cluttered and focus on linking to the important bits.


having 1.0.0 released as early as possible ... [the library] does not have to be perfect ...

@oblakr24 I am not a very experienced library publisher myself so I cannot comment on this but it is something for the creators to take an executive decision of. But a roadmap of implemented features and planned features is good to gauge if the library fits the needs.


These are just some suggestions and I would like to talk more regarding documentation and improving the library.

oblakr24 commented 2 weeks ago

@evant one more suggestion: the multiplatform docs and the front readme of the project could be clarified as to which platforms they support. They currently mention only Android and iOS but desktop also works, and wasm I did not try yet.

In fact I would recommend to put KMP support front and center in the main readme, as this is what will undoubtedly more distinguish this project from other Android-only frameworks.