I came across an architecture for a .net application where there are 3 layers
Repository layer (edmx and their classes)
^
|
V
Domain layer (Model -> Interfaces and their implementation)
^
|
V
Web layer (Model -> View models)
Communication between the web and the data layer takes place via Interfaces defined in the domain layer (anemic models)
The naming convention used over here is all dependent on table names
Repository layer
TableNameRepository.cs
TableName.cs (autogenerated files)
DomainLayer
ITableName.cs
TableName.cs
TableNameService.cs
Web layer
TableNameListModel
TableNameAddEditModel
The problem with this is that if a column is modified in the table, the classes in repository and domain layers all need re-work.
Also, communication between these layers take place with managers which have been resolved as below, where Container
is static
Container.Resolve<RepositoryManager>();
Container.Resolve<ServiceManager>();
The DBContext
is stored in session variables during the first call and removed at the end of the request. The second call will initialize the DBContext with the new
operator.
Any suggestions on what can be done (with minimal changes) so as to imporve this architecture so that it aligns with DDD.
2 Answers 2
Difficult to tell from your example, but this seems like a fairly standard design.
My only concern is around the manager classes and dbContext which would normally be hidden in the repository.
As to 'making it more DDD' you have a problem in that DDD would like you to be very OO and essentially move the service layer into the entity object. But this doesn't work well with a web/web.api service which is based on stateless calls to a service.
I wouldn't worry too much however, as its really just a naming issue and can be resolved by including the service objects in your design. ie rather than Purchasing an Order (Order.Purchase()
), a Till Completes an Order (Till.Complete(order)
)
Problem #1
"if a column is modified in the table, the classes in repository and domain layers all need re-work."
This is as it should be, The database stored the models, so if you change one you should change the other and vice versa.
If you are working with a legacy database system you can get around the problem to some extent by having the repository call stored procedures rather than the tables directly. This gives you an (additional) abstraction layer between the tables and the models
Problem #2
communication between these layers take place with managers which have been resolved as below, where Container is static
This is a bit bad. You should use a Factory class to instantiate your web layer, (im assuming C# mvc Controllers?) which knows about the container and retrieves and injects the required classes. This avoid having the static reference and calls to it.
I would start with a paper exercise: draw out a complete object model so that I understood the architecture fully.
Then I would try to see if there were any natural bounded contexts that became apparent. Then try to implement a new bounded context alongside the existing code, with new domain classes as needed, and encapsulate any business rules inside the domain objects (assuming these rules are elsewhere).
Assuming it all goes well the new bounded context should be able to replace a definite portion of the existing code, which you can remove later.
Then repeat as necessary.
Personally, I would TDD as I went along, as it would help me examine any assumptions I had made.
Explore related questions
See similar questions with these tags.
TableName.cs
: do they have behavior or only data?TableNameService.cs