There are several traditional architectures available, and one of the basic issues with these architectures is the coupling of UI and business logic layer to data access.
Typically, the data access changes every few years, and historically, the industry has modified data access techniques at least once every three years. Therefore, it is natural to expect some flexibility with data access layer when the system undergoes changes. Unfortunately, with tightly coupled systems, technology upgrades are always challenging. This can have a lot of impact on business critical systems, where the systems fall behind in the technology upgrade race and over time become legacy systems which are expensive and unwieldy.
In the year 2008, to overcome coupling and separation concerns Jeffry Palermo proposed ‘Onion architecture’. Onion Architecture has layers defined from core to infrastructure to control coupling. Its fundamental rule is that all code can depend on layers more central, but code cannot depend on layers further out from the core. In other words, all coupling is toward the center. This architecture is undoubtedly biased toward object-oriented programming, and it puts objects before all others.
In the center we see the Domain Model, which represents the state and behavior combination. Around the Domain Model are other layers with more behavior. The number of layers in the application core will vary, but the Domain Model remains central and since all coupling is toward the center, the Domain Model is only coupled to itself.
The first layer around the Domain Model is where we would find interfaces that provide object saving and retrieving behavior, called repository interfaces. The object saving behavior is not in the application core, however, because it typically involves a database. Only the interface is in the application core. Out on the edges we see UI, infrastructure, and tests. The outer layer is reserved for things that change often. These things should be intentionally isolated from the application core. Out on the edge, we would find a class that implements a repository interface. This class is coupled to a particular method of data access, and that is why it resides outside the application core. This class implements the repository interface and is thereby coupled to it.
The Onion Architecture is based on the ‘dependency inversion’ principle. The application core needs implementation of core interfaces, and if those implementing classes reside at the edges of the application, we need some mechanism for injecting that code at run time so the application can do something useful.
The database is not the center. It is external. Externalizing the database can be quite a change for some people used to thinking about applications as “database applications”. With Onion Architecture, there are no database applications.
More on this architecture in my upcoming blogs!