Ribs: Publish tool to enable easier adding of dependencies deep in the tree

Created on 9 Dec 2017  路  8Comments  路  Source: uber/RIBs

We often find ourselves adding new dependencies to child RIBs that are many levels deep in our tree. This can be quite cumbersome. Is there an easier way to add dependencies which are propagated through the RIB tree?

Here is an example:

MainMenu    (MainMenuComponent)
    |
    |
    |
    |____ProfileMenu    (ProfileMenuDependency, ProfileMenuComponent)
         |
         |
         |____ProfilePhotos    (ProfilePhotosDependency, ProfilePhotosComponent)
         |    |
         |    |
         |    |
         |    |__ImagePicker    (ImagePickerDependency)
         |
         |
         |
         |__ProfileSummary    (ProfileSummaryDependency, ProfileSummaryComponent)

To add a dependency to ImagePicker, say userID: String, we would declare it like this of course:

public protocol ImagePickerDependency: Dependency {
    var userID: String { get }
}

And then because this dependency is ultimately provided by MainMenu, we need to add this declaration to MainMenuComponent, ProfileMenuComponent, _and_ ProfilePhotosComponent

extension ProfilePhotosComponent: ImagePickerDependency {
    var userID: String {
        return dependency.userID
    }
}
extension ProfileMenuComponent: ProfilePhotosDependency {
    var userID: String {
        return dependency.userID
    }
}

...all the way up to the Root RIB (not shown).

At the Uber Mobility Meetup earlier this year, I seem to recall someone mentioning that Uber has an internal script that makes it easier to declare a new dependency at a grandchild level, and propagate this dependency all the way up the tree. Perhaps I misunderstood, but this tool sounds very useful. Are there plans to open-source such a thing?

enhancement

Most helpful comment

We just finalized the public API. We are moving onto documentation right now. Code generator development will start next week

All 8 comments

We typically use Swinject in our iOS project, and Dagger in our Android project, and these tools allow for O(1) effort for adding new dependencies, rather than O(N) (where N is the depth of the tree). I understand that the RIBs-Android library does indeed leverage Dagger as well, so perhaps my question is only applicable for the iOS subproject.

@neakor has been looking into this for iOS. No timelines though.

We are internally developing a tool, Needle, to provide similar automated DI as Dagger. We explicitly chose not to use Swiftinject because it is not compile-time safe.

Thanks for the information @neakor. That does seem to be the drawback of Swinject, and we're definitely enjoying the compile-time safety of the RIBs constructor-DI pattern.

Looking forward to playing around with Needle! The faster you open-source it, the faster we can help contribute ;)

@JakeSc Thanks for the interest. The tool is still currently under development. I can't promise a timeframe just yet. But I can say that we are developing this tool with an open source first approach.

Hi @neakor, any update?

We just finalized the public API. We are moving onto documentation right now. Code generator development will start next week

Was this page helpful?
0 / 5 - 0 ratings