Abp: Documentation: Domain Driven Design example

Created on 12 Mar 2019  路  3Comments  路  Source: abpframework/abp

There is BookApp example in Domain Driven Design => Application Layer => Application Services): https://abp.io/documents/abp/latest/Application-Services#bookappservice-implementation

Wouldn't be better to implement Create/Update/.... operations in a manager like in EventCloud application example?
https://aspnetboilerplate.com/Pages/Articles/Developing-MultiTenant-SaaS-ASP.NET-CORE-Angular/index.html#eventmanager
https://aspnetboilerplate.com/Pages/Articles/Developing-MultiTenant-SaaS-ASP.NET-CORE-Angular/index.html#eventregistrationpolicy

It's recommended that simple and then advanced example are "together" in the documentation since application based on ABP are enterprise-grade and therefore more advanced and complex most of the time.

question

Most helpful comment

Hi,

In DDD, there is no rule offers that an application service shouldn't create a domain entity. Application services can work with domain objects within given possibilities and restrictions.

In this example, creating a Book does not require any additional business logic that should be forced. I strongly recommend to not introduce complexity when it is not needed (YAGNI).

As an opposite example, TenantManager defines a Create method which is forced to use while creating a new tenant.

How we forced it? Simple: Declared the Tenant constructor as internal, so it can only be used in the Domain layer and Application layer should always use the TenantManager to create a new tenant. Why? Because the TenantManager ensures uniqueness of the tenanct name in the system, which is not possible to implement in an entity constructor normally.

As similar, changing name of a tenant is only possible through the TenantManager.

So, if I should write a rule for that, I would write these set of rules:

  1. Make it simplest possible (as a general rule :)
  2. Entity constructor should ensure validity of the entity.
  3. If an entity constructor can also ensure validity of the system, then the constructor can be public and directly be usable inside the application layer.
  4. If an entity constructor can NOT ensure validity of the system (like in the Tenant example), it should force to use a domain service by making the constructor internal (or with another way, but I don't want to extend the topic).

This is not only for constructor actually, but also valid for any method/property of the entity.

If one day you need to implement an additional logic while creating a new Book, you can refactor it. Don't hesitate to make such changes inside the domain and application layers. It is safe. It is not like making changes (or breaking changes) on public APIs of the system (App service methods and arguments for example).

This was the best practices in my opinion. But, for this specific document;

  • Each document should focus on its own concept (application services in this case) and should keep other concepts simpler.
  • Domain service document will already provide necessary information about domain services and include examples of domain service requirement.
  • Additionally, we can create a DDD document to explain best practices while it has lower priority since the ABP framework has many missing documents until come there :)

All 3 comments

Hi,

In DDD, there is no rule offers that an application service shouldn't create a domain entity. Application services can work with domain objects within given possibilities and restrictions.

In this example, creating a Book does not require any additional business logic that should be forced. I strongly recommend to not introduce complexity when it is not needed (YAGNI).

As an opposite example, TenantManager defines a Create method which is forced to use while creating a new tenant.

How we forced it? Simple: Declared the Tenant constructor as internal, so it can only be used in the Domain layer and Application layer should always use the TenantManager to create a new tenant. Why? Because the TenantManager ensures uniqueness of the tenanct name in the system, which is not possible to implement in an entity constructor normally.

As similar, changing name of a tenant is only possible through the TenantManager.

So, if I should write a rule for that, I would write these set of rules:

  1. Make it simplest possible (as a general rule :)
  2. Entity constructor should ensure validity of the entity.
  3. If an entity constructor can also ensure validity of the system, then the constructor can be public and directly be usable inside the application layer.
  4. If an entity constructor can NOT ensure validity of the system (like in the Tenant example), it should force to use a domain service by making the constructor internal (or with another way, but I don't want to extend the topic).

This is not only for constructor actually, but also valid for any method/property of the entity.

If one day you need to implement an additional logic while creating a new Book, you can refactor it. Don't hesitate to make such changes inside the domain and application layers. It is safe. It is not like making changes (or breaking changes) on public APIs of the system (App service methods and arguments for example).

This was the best practices in my opinion. But, for this specific document;

  • Each document should focus on its own concept (application services in this case) and should keep other concepts simpler.
  • Domain service document will already provide necessary information about domain services and include examples of domain service requirement.
  • Additionally, we can create a DDD document to explain best practices while it has lower priority since the ABP framework has many missing documents until come there :)

Maybe I didn't write clearly enough. :)
My whole point was that each example has to have a basic and advanced scenario (BookApp and CloudEvent app).
Many developers who started development in ABP/ASP.NET Zero don't leverage whole architecture and therefore methods inApplication/Web projects are long and full of business logic inside.

Excuse me for misunderstanding.

No problem @leonkosak :)
I tried to answer to both questions. One of the goals of the ABP project is to help developers to learn best practices. So, a DDD best practices document or tutorial would be good in the future.

Created an issue for it: https://github.com/abpframework/abp/issues/876

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hikalkan picture hikalkan  路  3Comments

zsanhong picture zsanhong  路  3Comments

wocar picture wocar  路  3Comments

hikalkan picture hikalkan  路  3Comments

ChangYinShung picture ChangYinShung  路  3Comments