Domain Layer should only contain Business Logic. This confuses me when I read about the Onion architecture, which states that the domain layer should contain all interfaces including services and repositories
Business Logic is the core responsibility of the domain layer. However, if that was strictly all the domain layer knew about, it wouldn't be able to communicate with anything else.
What you're being prohibited from putting in the domain layer is knowledge of the volatile, concrete, happens to be what we're using today, details of NHibernate, or the web, the database, the file system, or whatever else they want to use tomorrow.
The domain should be communicating by using whatever is convenient for itself to use, a data structure, an object, a collection. It should not be flinging around result sets, json, row tables, or anything else that gives away what it's talking to.
Which means you need to translate result sets, json, etc into, or from, those convenient to use things in a layer outside the domain. That's part of the infrastructure. That's the adapter part of the ports and adapters in Hexagonal Architecture which honestly isn't all that different from Onion Architecture or Clean Architecture.
The interfaces/abstractions needed to talk to that infrastructure, or have that infrastructure talk to the domain, are what the domain will know about. The domain will own them and dictate when and if they can change. Nothing else gets to have a say in how they change.
Doing that is what "removes all knowledge" of those outside details yet still allows for communication.
To answer #1 - when separating the domain model from the persistence model, change tracking is not a problem. The reason is that change tracking is more of a cross-cutting concern than a domain concern. The concern of a domain model is not to ensure that changes to itself are tracked.
The changes we want to track are typically the ones that we also persist. IOW, if, in the course of some processing, we change a property value and then change it back, there is no change to persist, which means there's also no change to track. So I'd lean toward change tracking as a behavior of the persistence, not the domain.
Edited:
Here's a note from Patters, Principles, and Practices of Domain-Driven Design:
Don't put dirty flags on domain objects
It might be tempting to put a flag on a domain object to signify that it has changed. The problem with this is that you are clouding the domain model with persistence concerns. Leave all change tracking to the unit of work and the repository.
For #2 - I don't have an open source example. But to start with, the separation between domain models and persistence models means ensuring that the persistence is abstracted, perhaps using the repository pattern.
If your domain models depend on a 'persistence ignorant' repository abstraction, like
public interface IRepository<T> where T : class
{
void Add(T item);
void Update(T item);
void Delete(T item);
void Get(RecordId id);
}
Then the implementation of that repository can map that T
to and from whatever persistence-specific model is needed, and the domain will never know that the persistence model even exists.
In order for this to happen, the domain needs to define its own repository interface rather than injecting one defined in some persistence library. That leaves the domain persistence agnostic and easier to test, and only the implementation(s) of that repository know about the details of the persistence.
Best Answer
Most probably the naming should follow some kind of DSL as proposed by Martin Fowler.
Without having any knowledge about the specifically addressed problem domain, it's hard to tell what you "can expect".
In the end it depends, how well the designers of some Domain Model grasped what is the most "natural naming" for their consumers and customers, and how the software developers can easily use these terms for their technical aspects.
That's the "creative part" (and art) software architects contribute, to glue the technical aspects and the problem domain specific terms together, such that it's easier to understand for the software developers and the customers at each other end.
The name of the Domain Layer of any system itself, is probably best described as "Domain Model or "Domain Layer".
Another highly related concept is the Domain Model (also from a Pattern Catalog proposed by M. Fowler).
I can't (counter) comment @Robert Harway's comment yet, though I don't believe that's entirely "opinion based". There are methodologies and techniques you can apply, to get that right as mentioned above.