has anyone used ktor with dagger?
# ktor
j
has anyone used ktor with dagger?
v
Havent used it with dagger but I know Koin provides docs on how to integrate with ktor
j
cool! thanks for the info 🙂
g
I did
e
Are there any advantages of using Dagger instead of Guice? There are no concerns over reflection performance like on mobile, no?
g
Compile time graph validation, much better runtime performance (yes, even on backend)
👆 1
e
I guess that the compile time has to suffer as well, do the benefits outweigh this cost? (I come from an Android development background, and I know how painful it can be waiting for the builds when you have Dagger in the project, haha)
g
Than you will pay runtime performance, application start performance and crashes during runtime because of broken dependencies graph, each of them literally may cost you not a few additional settings, but a lot of money This is why Google developing Dagger, because they use it on backend, including search
c
Not to revive an old thread… But are there any examples of using dagger with ktor? I’m working on a side project and just added and deleted dagger in the last 30 minutes. I’m having a hard time grasping how I’d use it when most of ktor is extension functions 😬
g
You create App class, inject dependencies into it, to configure ktor
I really don't see how it different using dagger with any kind of project of reasonable size
Also you can move different parts of your route to different classes inject them as multibings and inject in abstract way.
Maybe your app is just very small, so you don't see actual reason to separate different parts of it
p
@gildor Do you have a sample using the multibindings for routes? I'm using a different strategy for routes but I'm also moving those parts in separate classes.
I'm kinda curious now haha
g
I will show a sample a bit later. Essentially, just have a ln interface for this:
Copy code
interface RouterRegistrator {
   fun Routing.registerRoutes()
}
Copy code
//Which provided like:
@Binds @IntoSet fun myRoute(impl: MyRoute): RouterRegistrator
Copy code
//Then inject it:
class MyApp @Inject constructor (val routes: Set<RouterRegistrator>) {
Copy code
fun install(application: Application) {
  application.install(Routing) {
     routes.forEach { it.registerRoutes() }
  }
}
Code is not checked, just a draft of this idea
Returning to Cody's question, there are many more trivial examples of usage DI with dagger, you building your routing separately, even without multibindings, but you need some actual business logic, implementation of it, storage, database, clients of other services, I don't think you would write it inline in your routing declaration, you should provide it somehow, and this is where you need DI, and inject dependencies to routing declaration I don't say that you must use Dagger for DI, you can write it manually, or use other DI framework based on reflection, but every approach has own tradeoffs. But with Ktor dagger would work exactly the same in most cases
Opposite to trivial example, is having component scoped per request, or per authorized request, so you can build dependency graph per connection/user without need to write it manually and make it even more scalable (Depends on architecture of the app, of course)
p
I don't know if I prefer that to my current setup, but thanks I didn't know about multibindings
Here's a sample of a controller I use dagger with
c
@gildor I think where I get caught up is most examples of ktor I've seen show you creating a series of extension functions... So I don't have an App class, I have extension functions on the Application class and it's similar for the Routes too. So mainly just looking for some tangible example of Dagger being used with ktor so I can wrap my head around that. I've used Dagger a lot with Android but just having trouble connecting one dot to another. I've seen some examples with Guice so I may just base my Dagger implementation off of that.
g
Multibindings setup make sense if you have multiple Gradle modules, so you want make different parts of routing separated and pluggable, without this you have to inject all of them explicitly to some entry point which itself should be avare about all modules
👍 1
Your setup also make sense, but it eager to apply, so if this class instantiated it will add itself to routes
@Cody Engel problem with all those extensions is that they at some point start depend on each other explicitly and you pass dependencies between each other, so at some scale on top most level you have an extension with a lot of arguments which deliver them one to another Also it will work until you have one module only
Also not sure how Ktor is different from any other app. If comparing it with Android, Ktor routes is like AndroidManifest, but you need app/server config (like Android Application), you need implementations of routes (like activities). Sure you can bring all things together manually, same as with Android, but to make it maintainable and testable better to keep components simple and reduce cohesion between code, DI make sense. Again properly written manual DI can work at some scale, no doubts. But if you have hundreds of different routes in the app, some connected, some not, they should share configs, database, logging, third party services etc, to connect all this you need a huge class to just create it
c
Gotcha, I'll keep chugging away at learning ktor and will probably see a reason to use Dagger at somepoint. I'm not really planning on building a monolith with ktor so may never hit that point where I need a full fledged framework to handle it for me.