ritesh03/11/2020, 7:41 PM
as i dont want to trigger app-module build if any change in above to modules. And it has use cases and Dagger @Module class with above @Modules added (data and api) Something like this
app-module -> the ui layer, dependent on domain module using
@Module(includes = [ApiModule::class, DatabaseModule::class]) object AppModule
not api, and this module has Dagger components. Problem starts when dagger kicks in, whe dagger builds the graph it generated all the factories in the generated folder for providers in the sepecific modules like for ApiModule in its own and DatabaseModule in it's own and they are only exposed in domain layer and domain layer in app layer by impl. After compilation dagger throws AppComponent not found. The issue i found was it was not able to reach the generated factor classes from app-layer as app-layer is dependent on domain and domain on data and api-layer using
and changin to
fixed by issue. But, i dont want to go this way, because if any changes in the outer layers (data and api) the build will also be trigerred for app-layer if exposed by api. I am thinking of keeping the all providers classes in the domain-layer. I think it will work. Am I breaking any rules or there is a better way to do it.
mateusz.kwiecinski03/12/2020, 7:24 AM
domain-module-> dependent on above 2 usingdoesn’t sound right. Domain supposed to be independent, framework agnostic entity. It’s
which should depend on
After you inverse those dependencies you’ll find out that you don’t have a place which ties all components together. (which is the
in your current state) The solution is to separate app configuration from ui layer. To have a
module which would hold the ui and separate
which would contain application configuration. That should be the only module with flavours and buildtypes (as they define app configuration, right). In such case the
depends on domain (as every other data layer module in clean architecture context) and the app has reference to all of them. With such setup you can have a kotlin-only domain module (no need to add Android Framework dependency there) which makes sure that you don’t use any external dependencies. That may raise your earlier concern about:
i dont want to trigger app-module build if any change in above to modules.but as you can see, app module becames a tiny one, with almost no code. The most resource demanding
doesn’t get rebuild, as expected. In your case you’ll have to rebuild
which became the largest module each time you modify data layer class.
I am thinking of keeping the all providers classes in the domain-layer. I think it will work.That kind of solution hase a few downsides, mainly, you won’t be able to declare
classes visibility as internal. There shouldn’t be a need to expose them publicly. I’d expect that they implement interfaces declared in the domain and only those are exposed (from a module) using a DI framework. After you migrated your project to follow above pattern you might start considering what would happen if you started generating all DI classes within each module. Right now you’re using `@Module`s which generate providers, but the whole DI graph is still calculated within a single module which needs to have all dependencies (the issue you faced initially). With suggested approach, as the
becames the configuration holder, you can simply put
without worying someon will consume them in you UI code. Although, there is an alternative way to have more decoupled graph calcutaion and that could be achieved by exposin `@Component`s from each module, but that can be done only after all module dependencies are oriented in a proper way.
ritesh03/12/2020, 9:32 AM
Domain supposed to be independent, framework agnostic entity.
It’sI think since domain layer is the central layer, it can be dependent on the data layer, and provide the contract to data-layer, as in what it wants and data layer will implement. And all the business logic will reside in theand
db-modulewhich should depend on
inside the domain layer. Since modularization is in picture, and my ui-layer is dependent on the domain , and domain on data (local and remote). I dont want to expose through api, and leverage incremental build process.
I am thinking of keeping the all providers classes in the domain-layer. I think it will work.I was thinking earlier on doing the same, but it won't serve the purpose and not-ideal. having all generated classes there. I am not sure if this with dagger, that it's compiler is not modified to support
mateusz.kwiecinski03/12/2020, 9:55 AM
is the central layer, it can be dependent on the data layer.
It cannot if you're trying to follow clean architecture. Otherwise sure, you can try other patterns. And I'd argue if in such case domain can be called central layer. It's just in the middle and it happens only because you have simple project structure.
it's compiler is not modified to support
I'm not sure if that's dagger limitation. I'd rather point out at Gradle and how they isolate different classpaths (behavior introduced in gradle 5.0), but basically that's desired behavior. You shouldn't have data layer dependencies in any ui module classpath.
ritesh03/12/2020, 11:06 AM
And I'd argue if in such case domain can be called central layer. It's just in the middle and it happens only because you have simple project structure.Yeah, I agree with you here as there is no such rule, if domain should be the central layer, i have designed it as the middle layer which is only kotlin-lib to be unaware of any android stuff and consumes data from the outer layer and gives them contract/rules via interface and business logic via interactors (here its use-cases) and ui-layer will be consuming domain and use-cases. Any change in data, let's say remote or local, it wont affect the domain or ui and modularity and testable ofcourse. Not. a big project though so, i am okay with these 3 layers. My only issue is dagger here, not able to find the generated codes, which is in app-layer, where dagger component are build. To find them i need to expose the db and api layer using
which i dont want.
I'm not sure if that's dagger limitation. I'd rather point out at Gradle and how they isolate different classpaths (behavior introduced in gradle 5.0), but basically that's desired behavior.yeah I am not sure at this part. I was more hoping for dagger to generate the providers based on android module scope, which i am not if it's possible or i am making if any sense.
Javier03/13/2020, 1:25 PM
ritesh03/15/2020, 1:01 PM