7 Comments
User's avatar
Ivan's avatar

Great stuff! Thanx! Btw, should not you have dependency inversion in the API modules? It looks like API depends on the feature, but it should be other way around?

Jacob Bartlett's avatar

Haha you are right, I can never remember what way the arrows go. Heck, the compiler will tell me if I get it wrong irl 😅

Ivan's avatar

Yeah, me neither, but the nerd in me grabbed the keyboard first 😅

Tim's avatar

Can you screenshot your Xcode folder tree? Curious if you group by layers, how many packages you have, etc.

Jacob Bartlett's avatar

Probably can't share my exact tree for Granola but yeah basically have them sorted by layer then by module

Ruben Mimoun's avatar

Supposing (only supposing 😅) that Features receive injected dependencies. Would the API package be responsible for abstracting all the lower-level dependencies? Then, from the App module, would you resolve the concrete implementations, build the API (or some protocol-based dependency container), and inject that into the Feature? That way, the App target wouldn’t need to know about the Feature’s internal modules directly. But if that’s the case, wouldn’t some form of dependency inversion be required between the Feature layer and the layer below it?

Funny how one dependency graph can trigger an existential architecture crisis.

Jacob Bartlett's avatar

Oh no way more simple than that! Feature modules can just import whatever modules they need directly, the only rule is they can only import other feature API. With a decent DI framework the dep resolution is mostly abstracted and concrete resolution is a top level app concern