Well my application follows DDD design principles. It is an ASP.NET MVC application with the MVC web application being the presentation layer(I moved controllers to application layer though). It also has Application Layer that is primarily application services, use cases, etc. Above the Application Layer is the Domain Layer where Domain Models reside. Then there is Infrastructure Layer, which sits on top of everything else, and is supposed to be dependent on no other layers.
But there is one problem I noticed, that if Persistence Logic goes into Infrastructure Layer as the DDD books suggest, the Infrastructure Layer will have dependency to Domain Layer. The Repositories, for instances, need to know the types of Domain Models(Entities) to create, with this knowledge they become dependent on Domain Layer. The original DDD principles however, suggest that Infrastructure Layer should have absolutely no dependency for anything.
So now I am confused, should Persistence Logic really, belong to the Infrastructure Layer? If so, it makes Infrastructure Layer dependent on Domain Layer. If not, then where should it be? Application Layer? Or maybe a separate layer between Application Layer and Domain Layer(as application services use repositories, repositories use domain models). What do you think?
Types of Dependency
I think an important concept that might assist here is to distinguish types of dependency - specifically, a layer or component can be dependent on another layer because either:
is defined in terms of concepts defined in that layer, or
it uses the other layer - by delegating to that layer (aka calling methods on services in that layer)
Or both the above
Inversion of Control and Dependency Injection make this distinction even more important. They guide that we should depend on abstractions rather than concretions.
This means that, for example, the domain layer can define and depend on an abstraction of a repository - e.g. an IEntityRepository interface.
However, the implementation (concretion) is then implemented in the infrastructure layer.
When the application layer wants to call on the repository, it depends on the abstraction (the interface), and the inversion of control system (IoC Container) supplies it with an implementation from the infrastructure layer.
In this case, the infrastructure layer depends on the domain layer - but only in order to know about the interface it is implementing, but it does NOT depend on any other layer in order to delegate to it - it is the last layer in the call stack.
This concept resolves the conflict you were concerned about, because the infrastructure layer doesn't depend on anything else to carry out it's function.
Onion Architecture
Once you start to incorporate IoC concepts into thinking about your architecture, a model that can become very helpful is the onion architecture pattern. In this view, we retain the layered approach, but rather than thinking of it as a stack, think of it as a layered onion, with the Domain in the centre and the interactions with everything outside the application on the edges.
The original DDD books didn't specifically reference this, but it has become a very common pattern for implementing DDD systems.
It is also known as the Ports and Adaptor pattern, or the Hexagonal Architecture.
The idea is that it models dependencies in terms of 'knowing about' in terms of an onion - outer layers know about inner layers but inner layers don't know about outer layers.
But it models delegation of application flow in terms of movement across the onion - from one side of the onion to the other.
To be more specific:
The outer layer (also known as a 'primary adaptor') is where the request enters the system. The adaptor has the responsibility for handling a specific API presentation (e.g. a REST api) and transforming it into a request to the Application services layer - the next layer in. This is often represented as the top-left of the onion.
The Application services layer represents a 'use case' of the application. Typically a method would use a repository interface to retrieve an instance of an aggregate, then delegate to methods on the aggregate root to execute the business logic that involves changing the state of the aggregate as required for the use case. The application services layer, then uses another interface to ask the infrastructure layer to 'save' changes (often using a unit of work abstraction)
Here we have the application layer delegating control flow to an 'outer layer' of the onion (otherwise known as 'secondary adaptors'). This is often represented as the bottom-right of the onion, and is analogous to the 'infrastructure layer' in your description.
And this is where IoC comes in. Because we have an inner layer delegating to an outer layer, it is only possible because the outer layer has implemented an interface defined in an inner layer (which it can do because it knows about the inner layer). However, the IoC container injects the actual concrete implementation which effectively permits the inner layer to delegate control to the outer layer without being dependent on it.
In this conceptualisation, the request has flowed from the top left to the bottom right without the inner layers knowing anything about the outer layers.
There are 2 options here
1) Work with DAO objects. then the infrastructure layer only needs to know about those DAO objects. Especially if you use Entity framework or something similar then this isn't a bad strategy to follow. You do gain some overhead from mapping but you can use an Automapper for that.
2) live with the fact that the infrastructure knows about your DDD model. But since everything in DDD revolves around your domain model this isn't that bad of a tradeoff. (Especially if your domain model is very well understood and thus doesn't change radically). Be very careful though not to let your domain model be influenced because of database design. It should always be the database who follows, never the domain model where you don't make a certain change because it's hard to migrate in the database.
Persistence Logic usually belongs in the Infrastructure Layer, which is in the outer layer of the onion, and since the outer layers of onions depend on the inner layers, and the Domain Layer is in the center, then yes the Infrastructure Layer depends on the Domain Layer.
In DDD scope, the Persistence Logic should belong to Infrastrure Layer, as detailed persistence implementations are not the concern of Domain Layer.
However, as we think of the architecture of our projects differently, Infrasture Layer could either be dependent on Domain Layer or being depended on by it.
In a traditional layered architecture,
A linear dependency is suggested all the way passed from Presentation Layer, via Application Layer, Domain Layer to Infrastructure Layer.
In this case Infrasture Layer is deemed as an upperstream where both the interfaces and implementations of Persistence Logic are defined.
Domain Layer, as a downstream user, would follow the interface provided by Infrastructure Layer to fetch the entities, convert into domain objects, and then do the domain logic.
Typical codes in java:
// package com.xxxx.product.application
class ProductOrderApp {
private ProductRepository repository;
void orderOneProduct(String userCode, String productCode) {
ProductEntity enitity = repository.getOneByProductCode(productCode);
// 1. convert ProductEntity to Product Object
// 2. pass Product Object to Domain layer to do some logic
...
}
}
// package com.xxxx.product.domain
class Product { ... }
// package com.xxxx.product.infrastructure
interface ProductRepository {
// does not depend on any domain concepts
ProductEntity getOneByProductCode(String code);
}
class ProductRepositoryImpl implements ProductRepository {
#Override
ProductEntity getOneByProductCode(String code) {
ProductEntity entity = ... // get entity from some database
return entity;
}
}
In an onion architecture(as well explained in top answers),
Domain Layer is considered the upperstream, and all other downstream layers should follow the interfaces provided by Domain Layer.
Thus Infrastrure Layer depends on Domain Layer as in it implements the interfaces defined by Domain Layer. Domain Layer does not depend on Infrastructure Layer.
Typical codes in java:
// package com.xxxx.product.domain
class Product { ... }
interface ProductRepository {
// other Domain Logic can easily call this method as it uses Domain Objects for interection
Product getOneByProductCode(ProductCode code);
}
// package com.xxxx.product.infrastructure
class ProductRepositoryImpl implements ProductRepository {
#Override
Product getOneByProductCode(ProductCode code) {
ProductEntity entity = ... // get entity from some database
// persistence logic knows domain objects and do the convertion here
return convertToProduct(entity); // convert to domain objects
}
}
Related
I am implementing a Clean Architecture. I have four projects: Domain, Application, Infrastructure, and Presentation.
I have repository implementations defined in the Infrastructure. And I have the Repository Interfaces in the Domain.
I also have Services with a corresponding repository injected. For example, StudentService. I inject the StudentRepository into the StudentService.
My question is, where do I put the interface IStudentService? Should it reside in the Domain along with the interface IStudenRepository? Or is it more proper to place it in the Application?
I currently have my IStudentService in the Application project. But my understanding is to have loose coupling and placing all Interfaces in the Domain project. Is my understanding correct?
It is generally a good practice to place interface definitions in the Domain layer of a Clean Architecture application. This is because the Domain layer represents the core business logic of the application, and interfaces are an important part of defining the contract for that logic. By placing interface definitions in the Domain layer, you can ensure that the Domain is decoupled from the implementation details in the other layers of the application.
For example, in your case, the IStudentRepository interface would be defined in the Domain layer because it represents the contract for how the StudentService can interact with the student data store. The IStudentService interface would also be defined in the Domain layer because it represents the contract for the business logic related to students.
By placing both of these interfaces in the Domain layer, you can ensure that the Domain is decoupled from the implementation details in the other layers of the application. This makes it easier to change the implementation of these interfaces without affecting the rest of the application.
In summary, it is generally a good practice to place interface definitions in the Domain layer of a Clean Architecture application in order to ensure loose coupling and separation of concerns.
To implement Clean Architecture follow the following steps:
Domain Project:
Domain should have just entities such as "Student" Entity.
Application Project:
Application should have interfaces and services and the implementation of services.
Infrastructure Project:
Infrastructure should have the implementation of interfaces that are defined in the Application, and DbContext class.
The presentation should have the UI.
I am a new comer in DDD concepts and I am trying to design a solution structure strictly follow DDD & Prism (WPF).
I am stacking at where to create DTO project (Data Transfer Object). As I know, DDD will have 4 general layer:
Presentation
Application
Domain
Infrastructure
So that, would you please tell me which layer for the DTO project belong to?
I have refered at: DDD - which layer DTO should be implemented
Some one told that we should implement it at Service layer, but I think It is not make sense, cause of follow DDD concept, we don't have which called Service layer.
Thank you so much,
Regards
Generally speaking, the location of the component's code should stay besides the owner of that component. The owner has full control of its components. This idea follows the dependency inversion principle.
So,in your case, who is the owner of the DTO? Who controls the structure and the purpose of that DTO?
Using DDD (in any architecture!) you should, however, take into account that domain code should not depend on infrastructure, application or UI code. So, if you decide to put the DTO class into the application layer then you cannot refer to that DTO from your domain code (i.e. a domain entity or a domain service cannot have any references to the DTO class - no import or use directive or new statements)
You might be disturbed by my answer, but I have to repeat again:
Domain-Driven Design is not about layers. It is about Domain and Design.
Domain is your problem space. This is what your users need. This is what your domain experts tell you to do.
Design is how you model your solution. It starts from the knowledge you got by speaking to domain experts. It continues with deciding what are your bounded contexts and how they are placed on the context map. Then you decide how to implement each context - would this be a Domain Model, Active Record, CRUD or some off-the-shelf software.
When you decided on the implementation, you can think of the internal structure and DDD does not dictate anything there.
If your question is where to put DTO for the data - well, they might be located in a separate project if more than one other project uses them, or you put them to the DAL (which is typical) since your presentation layer will most probably use it directly, without involving the domain model, otherwise you won't be mentioning DTOs at all.
Concerning using the term DDD for your question, I wrote a blog post some time ago, targeting this issue, which you might want to read.
I see that we should add DTO classes in the layer will create objects of them to send their to another layer.
In DDD model the Application layer and Infrastructure layer already can access the Domain layer so they don't need DTOs in the infrastructure layer because it will return entity class.
Based on the above we need DTOs to represent the data retrieved from the DB(through Infrastructure layer) in the Application layer and send these data using DTOs to the Presentation layer without making Presentation layer get access the domain entities which are contained in the Domain model layer.
Finally, from my experience and using the DDD model I prefer to add DTOs in a separate project inside the Application layer. which means it belongs to the Application layer.
You can see the sample of my project and the "Core layer" in it means the "Domain Layer"
Also you can read Excellent detailed explanation for DDD model from Microsoft
I'm having trouble finding an answer to this. Basically, right now I have these layers:
Data Access Layer (where my repositories are). It has Namespace Hello.Data
Business Layer (where my business objects are). It has Namespace Hello.Business
My repositories will return business objects. For example, GetCustomer will return Customer.
However, in my business layer, I also want to add logic that will use the repository to add/update/delete records, so I can reuse those methods in my MVC controllers. This doesn't work though, since I can't have my Data Access Layer reference my Business Layer and also have my Business Layer reference my Data Access Layer. (It creates a circular reference that is not allowed).
What do you guys think is the best solution? Should I put my Business Logic into it's own project?
So instead of:
Hello.Data
Hello.Business
I'll have:
Hello.Data
Hello.Business
Hello.BusinessLogic
Or am I thinking about this all wrong? Thanks!
Why would you separate business logic from business models? The logic should be in the models.
The business logic layer shouldn't have to reference anything, aside from maybe small common utility libraries. Basically, it should have no dependencies on infrastructure concerns (like application technologies, database technologies, etc.). It should contain just business logic.
All other layers should reference the business logic layer.
This doesn't work though, since I can't have my Data Access Layer reference my Business Layer and also have my Business Layer reference my Data Access Layer.
Correct! The mistake in this design is that the business logic layer references the data access layer at all. It shouldn't.
It should, however, contain interfaces for data access (and other infrastructure concerns) which are implemented by the data access layer. The business logic layer only needs to know about the interfaces, it doesn't know or care what implements those interfaces.
A dependency injection container would then be used to connect implementations to interfaces.
The application layer references the dependency injection layer to initialize it and pass the container (which itself implements a generic business logic interface) to the business logic layer.
The dependency injection layer references the business logic layer to know about the interfaces and references the data access (and other infrastructure) layer to know about the implementations.
The data access (and other infrastructure) layer references the business logic layer to know about the interfaces to implement.
The business logic layer doesn't reference anything. It requires a configured dependency injection container and uses that container to get implementations for interfaces.
If DbContext is in the DAL then the generic type arguments of the DbSets cannot be the BLL classes (domain model). What are the best practice ways to separate these layers? An extra model in the DAL? Interfaces?
If you're doing DDD, I believe the repository (at least the interface for it) is part of your business / domain layer. Your implementation of the repository will be a separate assembly which would have to reference that business / domain layer. So your DAL knows about your business objects, but not the other way around. To do dependency injection, you'll probably have in your DAL layer something that configures your container to use Repository for your IRepository interface. If you need a unit of work patter, your interface would likely have to be part of the business layer as well. Again your implementation will be in your DAL and the DAL would configure the DI container appropriately. This is actually one of the things I dislike about the repository pattern, as you either need to ensure your users of your interface correctly manage the IUnitOfWork, or you need something to wrap the repository which does so.
In a traditional n-layer architecture, things are a bit different. In that case your business layer can talk to the DAL, and I've normally built the DAL to have DTOs which represent a row of data in the database. The business layer will then use these DTOs to hydrate the business objects (or if you're using something like CSLA.Net, the business objects know how to hydrate themselves).
Either way there shouldn't be a situation where you end up with a circular reference.
I usually consider the domain model as a separate layer.
If we look at the classic MVC paradaigm, then the model is used by both the View and the Controller.
No reason why it shouldn't be used by the DAL as well.
The Model, however, will not reference the DAL; all operations against the data store will be done by the controller.
So the general flow of things would be-
user interacts with the View
View invokes a method on the Controller
Controller uses the DAL to retrieve Model objects
Controller invokes methods on Model objects, saves them (using DAL) if necessary, and returns an answer to the View
Your BLL or Domain Layer should not worry about data access technical details, BLL shold be technology independent. If you want to stick with Entity framework you should generate POCO entities and move them to seperate layer, this way you can avoid circualr references.
Can anyone help, I have 2 applications and they are nearly identical. they have a completely different presentation layer (web) and the business logic and database are nearly identical. Basically one app has some things that the other doesn't.
so i was wondering if i can do the following without breaking any rules etc
Each app has their own presentation layer.
Each app has their own service layer.
Each app has their own data access layer.
Each app shares another service layer.
Hence the shared service layer both apps can access as the business logic is identical, but they both have another service layer which has 5 or 6 methods in there which are specific to that actual app
The data access layer - I don't see anyway of sharing this as there are 2 different db's with entity framework hence its got the EDM in there so its not dynamic - and the tables differ slightly.
I could use IOC on the shared data access layer I suppose
Would anyone help or comment weather this is good practise.. What I didn't want to do is have only a separate service layer when a lot of it is shared..
Is this a good idea? Maybe i have got it wrong, is there a better way?
As Arjen de Blok said, your business entities should use a repository, a repository is an object with methods to query, update or insert domain entities.
The interface which describes your repository belongs to your domain layer, but the implementation belongs to the infrastructure layer (DAL).
You can share the domain and infrastructure libraries between your two projects. If these two projects should retrieves their data through a shared web service or a shared database, you just have to choose (i.e inject) the correct implementation of your repository (your domain objects know only about the interface of your repository, not about the concrete type)
If the business logic is mostly identical then you should focus to this first.
If you want to do DDD then you should identify your entities and (business) services first and place these in a single library.
These entities and business services should talk to your infrastructure layer (your DAL).
If the infrastructure layer is very different in these two applications then try to work with interfaces. So wrap the intfrastructure layer with interfaces and only talk from the domain layer to your infrastructure layer via these interfaces.
To bind your business logic to your infrastructure's implementation you could use IoC/DI.
You could unify the DAL with a Repository interface. You could then implement the interface across projects. You will probably end up with a EF Repository base class as well. You could apply a similar technique to the services, leverage a common interface and then specialize the service implementations.