11.7.  Restricting Dependency Types

Sometimes you are in a situation, where you allow one artifact to use another one, but would like to restrict the usage to dependencies of a certain type. For example let us assume you do not want the UI layer to create new instances of classes defined in the "Model" layer. Only "Business" and "Persistence" would be allowed to create "Model" instances. You can solve this by creating a new interface that restricts the usage of certain dependency types:

artifact UI
    include "**/ui/**"
    connect to Business, Model.UI
artifact Business
    include "**/business/**"
    connect to Persistence, Model
artifact Persistence
    include "**/persistence/**"
    connect to Model
artifact Model
    include "**/model/**"
    interface UI
        include all // everything in "Model"
        exclude dependency-types NEW

Now it would be marked as an architecture violation if a class from the UI layer would create a new instance of an object from the model layer. Please note that we had to remove the public modifier from "Model". If we had kept it there would have been an implicit connection from UI to the default interface of Model bypassing our special restriction.

Currently the language supports the following list of language agnostic abstract dependency types:

        // instance creation
        // inheritance
        // interface implementation
        // function or method calls 
        // reading a field or variable
        // writing to a field or variable
        // all other uses

In the next section we will look at another advanced concept called "connection schemes".