Thread
#dagger
    s

    Sagar Suri

    2 years ago
    Question regarding the usage of
    @Singleton
    and
    @Inject
    inside the code instead of
    Module
    ? I have a personal opinion of creating
    Modules
    and defining all my dependencies there instead of marking classes with the above annotations? Reason being:1. It help me understand the dependencies and configurations from a single file i.e
    Module
    . 2. It avoid mixing code with configuration(annotations). What are your opinion on this? I don’t prefer the following code:
    @Module
    class BookingDatabaseModule {
    
        @Provides
        fun provideBookingDao(database: BookingDatabase) = database.bookingDao()
    }
    Following is my preferred way of doing it:
    @Module
    class BookingDatabaseModule {
    
        @Provides
        @Singleton
        fun provideDatabase(context: Context) = BookingDatabase.newInstance(context)
        
        @Provides
        fun provideBookingDao(database: BookingDatabase) = database.bookingDao()
    }
    What are your opinions?
    Ianmedeiros

    Ianmedeiros

    2 years ago
    It’s a matter of taste. If you use @Inject, it will save a LOT of code, with the downside of the dependency graph being less evident -> you can use https://github.com/arunkumar9t2/scabbard to make it more visual if you want
    It’s better to discuss it with your team than here. Any approach works and you need to choose which one makes your team more confortable IMO
    gildor

    gildor

    2 years ago
    We use constructor injection everywhere where it's possible, it saves a lot of code Personally I don't find that it makes graph less understandable, a bunch of modules with boilerplate, especially without good structure, doesn't make it better
    There are different opinions on topic, some think it's make hard to understand source of dependency, but as I said, I personally don't see such problem
    s

    Sagar Suri

    2 years ago
    @gildor how if you want to change the DI library someday? Which basically doesn’t work with these annotations?
    gildor

    gildor

    2 years ago
    What is problem with it? It's just an annotation on constructor, it doesn't add any dependency on any library. You can even drop DI library completely and rewrite graph manually, it wouldn't require any changes on dependency level
    s

    Sagar Suri

    2 years ago
    Yeah it’s basically how people are comfortable with. I personally want to keep these DI configurations in one place.
    gildor

    gildor

    2 years ago
    Also @Inject is part of JSR-330 standard and supported by many DI frameworks: spring, juice, toothpick
    Keep configuration in one place? What kind place? Isn't huge dagger module with all classes of your app (or even Gradle module) is a mess? So you have to split to multiple modules it it's possible, but it'w also not so easy to manage
    s

    Sagar Suri

    2 years ago
    I meant, if you have a room database implementation..you will create a database module which will hold the creating of database logic and if required by a LocalSource class.
    gildor

    gildor

    2 years ago
    Usually every feature has own module (or a few modules connected to graph), but most of them are just bind declaration, so you connect interfaces with implementation, tho it looks similar, but because of constructor injection for constructor it requires much less code and more declarative
    Database module sure, if you need config on DI level, but usually you have very few such dependencies, andost of classes just require other classes, and no special config
    We have thousands classes which we inject, I just cannot imagine also write manual constructor injection for all of them... I mean it's possible, but disadvantage is huge for me
    s

    Sagar Suri

    2 years ago
    Right! Make sense to me. @gildor
    Colton Idle

    Colton Idle

    2 years ago
    Interesting discussion. I'm learning dagger and feel a lot of the same points. I would love to open up a single package with a whole bunch of modules defined and then you can very easily find out which Modules/Dependencies are available to you. Using @Inject feels like you're hiding the dependency, but I just started working with dagger, so I don't really know. It's just how I feel at this point. I will say that I think it's crazy that Scabbard keeps being brought up here because... like... what did you do before Scabbard? If I'm brand new to a team and writing a new feature, how do I know what dependencies are available to me, etc? So many questions. 😄
    s

    Sagar Suri

    2 years ago
    So true @Colton Idle Even I also feel the same.
    gildor

    gildor

    2 years ago
    Why do you want to have all modules in the same package, if those modules are not related? Why do you want to know which dependency is available to you, if essentially every class is available? When you inject everything no need to know what is available, also dagger will check it for you on compile time Why inject is hiding dependency? You hide or expose dependency by making them public/internal, not by defining provides method for them
    Colton Idle

    Colton Idle

    2 years ago
    @gildor
    Why do you want to have all modules in the same package, if those modules are not related?
    For me, it's because when I start a new project, I think it would be really nice to have one spot to look at and find out what dependencies I can start injecting into whatever new feature I'm working on. A lot of times when I'm new to an existing codebase and it uses Dagger... I'm left thinking "What the hell is available for me to use?" So I'm not advocating to have all modules in the same package, I'm just saying that I wish there was an easy way to to just see all modules or all provides methods, or just really... What is everything that I can start injecting? That's what I find hard as a 2 week user of Dagger. People mention scabbard, but it seems crazy that if Dagger is used to help provide dependencies in a consistent way, that there would be a way to quickly view what dependencies are injectable if I want them.
    Why do you want to know which dependency is available to you, if essentially every class is available? When you inject everything no need to know what is available, also dagger will check it for you on compile time
    Let me give you another example. I started working on a project with a barebones Dagger setup. It was basically just used for sharing OkHttp/Retrofit instance. They plan on using dagger more. Okay cool. Makes sense. I code up a new feature in Android with SharedPreferences and then in code review they tell me "Oh this is actually available through Dagger" and it's like. 🤦 I wish there was an easy way to see what dependencies have been set up in dagger for me to use. On the opposite side of the spectrum I've worked on projects with like 1000 dependencies and it's literally impossible to know what I have available to me when building my feature until I kind of start guessing. I guess maybe this could just be solved by docs in the project keeping a master list of everything that's available. Maybe this isn't a problem at all! Maybe I'm just making it up because I'm new to dagger. /shruggie This is a beginner perspective. Would love for someone with more experience to break me out of that thinking.
    Why inject is hiding dependency? You hide or expose dependency by making them public/internal, not by defining provides method for them
    Similar to what I said above. You are making sense, but it still doesn't help me in the use case where I'm new to a project, and I jump in and start writing a feature "Hmm I'm going to need Retrofit and SharedPreferences (purely hypothetical example) I search for all classes that end in Module, and only find one (in this hypothetical example) and the only thing it provides is Retrofit. So now I'm like, Okay, I will Inject retorfit as a field, but now I need sahredPreferences. Then at code review time, they tell me "Oh actually we have this SharedPrefWrapper class that has an @Inject on it's constructor, so you can use that". I'm complaining about visibility and not knowing what's there quickly.