Home > other >  C# (VS2019): How to separate a domain layer from a data layer when both use a class using VS project
C# (VS2019): How to separate a domain layer from a data layer when both use a class using VS project

Time:12-16

I have a simple IS that is following a three-layer architecture. So far I have had all code in one project and separated by files. I understand, that using Visual Studio IDE, components should be packed in separate VS projects within the VS solution. Separating the presentation layers in a project is not a problem, but I have trouble separating the domain layer and the data-access layer. The database is accessed by a data mapper, that returns a domain object holding the data for the domain logic. But this object is defined within the domain layer component and since there should not be cyclic references between the components, I do not know how to solve the problem with one class being necessary in two components.

Should I copy-paste the declaration? But then every change must be mirrored in both components manually. Or is there something wrong with my understanding of the mapper or the layers?

CodePudding user response:

Think of the layers of your application as an onion - an innermost layer with another layer around it and a third layer around that. A layer can reference layers within itself, but it cannot reference layers outside itself.

The innermost layer is the domain project - this doesn't reference any of the other projects and typically has few if any external dependencies.

The next layer out is the data access / repository project - this references the domain project because it's responsible for writing domain objects to the data store and reading them from the data store. It probably also references some external packages such as Entity Framework to assist with accessing the data store.

The outermost layer is the UI / presentation project - this can reference both the domain project and the data store project because it can create, manipulate and display domain objects and it can also tell the data access layer to read and write to/from the data store.

For more complex applications you may want more than one project per layer, or you may want more than 3 layers, and you may want to pass DTOs (Data Transfer Objects) or view models to/from the presentation layer rather than passing domain objects through all the layers. There are many questions here already on that subject, such as Should services always return DTOs, or can they also return domain models?, and there's no one-size-fits-all answer, but 3 layers with one project per layer is a good place to start for now.

The key breakthrough for me in understanding how to separate the domain layer from the data access layer was understanding that domain objects don't need to know how to write themselves to or read themselves from the data store because that's the responsibility of the data access layer, so the domain project does not need to reference the data access project. The domain layer neither knows nor cares whether your data store is a SQL Server database, a bunch of text files or an imp with a notebook (gratuitous Discworld reference).

So, returning to the original question,

Should I copy-paste the declaration? But then every change must be mirrored in both components manually.

For a small application it's fine for the data access layer to use the classes defined in the domain layer. For larger applications you may want to define data access layer versions of your domain classes, but only if there's value in doing so. Don't duplicate code just for the sake of following a pattern - use the pattern that's right for your application.

  • Related