Rule for nesting of packages
Is there a way to express that classes of a more general package must not access classes of more specialized (or sub) packages?
Rationale: based on an hexagonal architecture style I have my domain classes for example in
com.enterprise.business.domain
The corresponding repository interface is
com.enterprise.business.domain.repo
The specific mongodb implementation could be in
com.enterprise.business.domain.repo.mongodb
etc
So classes in an outer (e.g. com.enterprise.business.domain.repo.mongodb) package can access classes in the base com.enterprise.business.domain package, but never the other way around.
I would like to express this restriction in a general manner.
Something like: a class in some package X must not access a class in some package Y where X is a package prefix of Y.
You can't do this in the general form, but what you can do is define the following slicing:
classpath().withSlicing(
"hex-architecture",
"com.enterprise.business.(domain)",
"com.enterprise.business.domain.(repo)",
new NamedPattern("implementation", "com.enterprise.business.domain.repo.**"))
This will prevent cycles between domain repository and implementation. So if you have a single dependency in the correct direction the back direction is prohibited. If you want you can make the direction explicit:
classpath().withSlicing(
"hex-architecture",
"com.enterprise.business.(domain)",
"com.enterprise.business.domain.(repo)",
new NamedPattern("implementation", "com.enterprise.business.domain.repo.**"))
.allow("implementation", "repo", "domain")
if you want to use it accross multiple business modules, you can use wildcards:
classpath().withSlicing(
"hex-architecture",
"com.enterprise.*.(domain)",
"com.enterprise.*.domain.(repo)",
new NamedPattern("implementation", "com.enterprise.*.domain.repo.**"))
.allow("implementation", "repo", "domain")
Note: I think the repositories interfaces should be in the same package as the domain, but that's just me with my limited understanding of your situation
Thanks for your reply. Well, the repository example was just that, an example.
Ok, you said this is not possible in the general form.
However, are there ideas or is there an API to extend the DSL with custom constraints?
As far as I can see after looking very briefly at the implementation of the degraph-check module it seems I would need to provide a custom Constraint implementation and add that to the ConstraintBuilder. How would I do that?
Sorry there is currently no sane way to do that. I'm aware of that limitation and are planning to make major changes to this area to enable this. But I have currently no idea, when this might happen.
Alright, then consider this as a feature request for programmable custom constraints. Perhaps I will find the time to dig deeper into the degraph sources to come up with a proposal. :-)
then consider this as a feature request for programmable custom constraints.
Already did that.
The rough plan for implementation involves removing the constraints from the configuration and creating Matchers for them. This also means creating an API for accessing the dependency graph, which in turn should enable custom constraints.