Validation and data persistence in a domain model

My (first and current) workplace (a .NET shop) suffers from an over-abundance of anemic domain models, to the extent that I don’t really know how validation and data persistence should be handled in a proper domain model.

Data Persistence

One option would be to give the domain model a way to do persistence itself. You could, for example, inject an IFooRepository via constructor injection, and have that resolved by an IoC container to ensure you don’t create a dependency on it (à la onion architecture). But I’m not sure if the code that uses the domain model should be responsible for calling methods to save the data, etc., or if it should be done implicitly behind the scenes on a background thread. Perhaps this breaks that purity of the domain model and is more along the lines of the active record pattern.

The other option I see is to not tie the domain model to data persistence at all and instead have a coordinating service layer responsible for that aspect.

What are the best practices for data persistence in the domain model pattern?

Validation

Another problem I don’t know how to solve with a proper domain model is how to indicate to the UI why the current model state is invalid without coupling to (or at least catering to) the UI. For example, let’s say I have a form an user fills out with various fields. We want to validate that input, and if something is wrong, indicate an error on that specific field with a message.

How would we handle validation with that level of granularity without adding significant complexity to the domain model, or doing hack-ish stringly-typed things (like throwing an validation exception with the property’s name and a message)?

I could be mistaken in my understanding, but I believe your trying to redesign your Domain Model so that it isn’t riddled with anemia. A couple of really, really great books on the matter are:

  • Martin Fowler – Patterns of Enterprise Application Architecture
  • Eric Evans: Domain-Driven Design: Tackling Complexity in the Heart Of Software
  • Vaughn Vernon: Implementing Domain Driven Design

They have a lot of content which answers quite a few questions on your goal. One of which is:

A rich Domain Model can look different from the database design, with
inheritance, strategies, and other Gang of Four patterns, and complex
webs of small interconnected objects. A rich Domain model is better
for more complex logic, but is harder to map to the database.

A simple Domain Model can use Active Record, whereas a rich Domain
Model requires a Data Mapper. Since the behavior of the business
subject to alot of change, it’s important to be able to modify, build,
and test this layer easily.

That is an excerpt from Fowler. He will go into details about the model being anemic and bloated models as well. The scope of the question to me appears quite large; so I’m not sure I could delve far into it. Those books should point you in the right direction; also will allow you to gauge your current project and implementation to refactor it quickly.

From a relatively basic understanding:

You should be able to abstract your model, which will allow a brief overlay of the UI and Data Access into your Domain Model. But otherwise the model should allow a clear, clean, concise implementation which will help separate responsibility.

Sorry I couldn’t be more help.

The question arises what your UI is using to get the data and how it sends the data to be persisted. I’m afraid since you mentioned you have no service layer and you suffer with finding the right place for your validation, that your UI works directly with your domain classes. That could be the way to go, however it does not sound like a very complex application and you can do persistance work and querying right in the UI code. You can check posts of Ayende Rahien and many others who talk about getting rid of repositories. In relatively simple scenarios ORM is capable to provide enough isolation of domain model from the persistance itself. Also it is a questionable matter if modern ORMs can be seen purely as DAL. Look at NHibernate, it can do so much more than just mapping simple tables to simple classes. And if you look at your repositories you might find a bunch of methods called GetByThis and GetByThat, which issue a simple query to the ORM (if you use one of course) and just play a silly role of unneeded abstraction to make an impression that you do DDD.

Concerning your comment about “not creating” dependencies by injecting repositories – you will onvert control but you will have dependency as soon as you use repository class instance in your domain object. It does not matter how it gets there. So this is the worse choice of all.

To your validation question I would recommend you to look closely to your validation as such and decide what validation is domain specific and what is more data entry specific. Data entry validation like mandatory fields should not be checked by the domain model. It is a simple job and UI layer is perfectly capable of doing that. Even more, most of modern UIs are able to do this validation very easily. However you need to find a way to inform your UI about the data input rules (I will get back to it below). Your domain model need to perform more business-oriented validation, like if customer with such name already exists. But you, again, cannot do this inside your domain class since you are unable to query existing data from there because it is not the domain object responsibility to care about anything outside of its own aggregate.

So if you want to go to deal DDD journey I would recommend you to look at CQRS principle. It is often bound to event sourcing but you can just skip that. Concentrate on this scenario, when using RDBMS with or without ORM or NoSQL for persistence:

  • Create input models and view models to be used solely by the UI.
  • Decorate your input models with data attributes for client-side validation.
  • Send commands from the UI to your backend to do business validation and persistence.
  • Send queries to your backend from the UI to get the data to show. Returned data should be placed in view models.
  • Use domain events to communicate between different bounded contexts

It does not necessarily require the backend logic to be put in an application server (although it is very desirable to enable having multiple UIs with the same backend). You can use in-memory events to send commands and queries too.

But again, look at what you really need, don’t try to overscale your abstractions just because the book says so. Remember that very often abstractions are put in place just because someone heard this is a good thing. Repositories is a classic example, when people say it makes their system persistence ignorant and they can change their ORM but in fact no one does that. When ORM is changed it means almost full redesign and repositories get scrapped equally well together with all other code.

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa

Validation and data persistence in a domain model

My (first and current) workplace (a .NET shop) suffers from an over-abundance of anemic domain models, to the extent that I don’t really know how validation and data persistence should be handled in a proper domain model.

Data Persistence

One option would be to give the domain model a way to do persistence itself. You could, for example, inject an IFooRepository via constructor injection, and have that resolved by an IoC container to ensure you don’t create a dependency on it (à la onion architecture). But I’m not sure if the code that uses the domain model should be responsible for calling methods to save the data, etc., or if it should be done implicitly behind the scenes on a background thread. Perhaps this breaks that purity of the domain model and is more along the lines of the active record pattern.

The other option I see is to not tie the domain model to data persistence at all and instead have a coordinating service layer responsible for that aspect.

What are the best practices for data persistence in the domain model pattern?

Validation

Another problem I don’t know how to solve with a proper domain model is how to indicate to the UI why the current model state is invalid without coupling to (or at least catering to) the UI. For example, let’s say I have a form an user fills out with various fields. We want to validate that input, and if something is wrong, indicate an error on that specific field with a message.

How would we handle validation with that level of granularity without adding significant complexity to the domain model, or doing hack-ish stringly-typed things (like throwing an validation exception with the property’s name and a message)?

I could be mistaken in my understanding, but I believe your trying to redesign your Domain Model so that it isn’t riddled with anemia. A couple of really, really great books on the matter are:

  • Martin Fowler – Patterns of Enterprise Application Architecture
  • Eric Evans: Domain-Driven Design: Tackling Complexity in the Heart Of Software
  • Vaughn Vernon: Implementing Domain Driven Design

They have a lot of content which answers quite a few questions on your goal. One of which is:

A rich Domain Model can look different from the database design, with
inheritance, strategies, and other Gang of Four patterns, and complex
webs of small interconnected objects. A rich Domain model is better
for more complex logic, but is harder to map to the database.

A simple Domain Model can use Active Record, whereas a rich Domain
Model requires a Data Mapper. Since the behavior of the business
subject to alot of change, it’s important to be able to modify, build,
and test this layer easily.

That is an excerpt from Fowler. He will go into details about the model being anemic and bloated models as well. The scope of the question to me appears quite large; so I’m not sure I could delve far into it. Those books should point you in the right direction; also will allow you to gauge your current project and implementation to refactor it quickly.

From a relatively basic understanding:

You should be able to abstract your model, which will allow a brief overlay of the UI and Data Access into your Domain Model. But otherwise the model should allow a clear, clean, concise implementation which will help separate responsibility.

Sorry I couldn’t be more help.

The question arises what your UI is using to get the data and how it sends the data to be persisted. I’m afraid since you mentioned you have no service layer and you suffer with finding the right place for your validation, that your UI works directly with your domain classes. That could be the way to go, however it does not sound like a very complex application and you can do persistance work and querying right in the UI code. You can check posts of Ayende Rahien and many others who talk about getting rid of repositories. In relatively simple scenarios ORM is capable to provide enough isolation of domain model from the persistance itself. Also it is a questionable matter if modern ORMs can be seen purely as DAL. Look at NHibernate, it can do so much more than just mapping simple tables to simple classes. And if you look at your repositories you might find a bunch of methods called GetByThis and GetByThat, which issue a simple query to the ORM (if you use one of course) and just play a silly role of unneeded abstraction to make an impression that you do DDD.

Concerning your comment about “not creating” dependencies by injecting repositories – you will onvert control but you will have dependency as soon as you use repository class instance in your domain object. It does not matter how it gets there. So this is the worse choice of all.

To your validation question I would recommend you to look closely to your validation as such and decide what validation is domain specific and what is more data entry specific. Data entry validation like mandatory fields should not be checked by the domain model. It is a simple job and UI layer is perfectly capable of doing that. Even more, most of modern UIs are able to do this validation very easily. However you need to find a way to inform your UI about the data input rules (I will get back to it below). Your domain model need to perform more business-oriented validation, like if customer with such name already exists. But you, again, cannot do this inside your domain class since you are unable to query existing data from there because it is not the domain object responsibility to care about anything outside of its own aggregate.

So if you want to go to deal DDD journey I would recommend you to look at CQRS principle. It is often bound to event sourcing but you can just skip that. Concentrate on this scenario, when using RDBMS with or without ORM or NoSQL for persistence:

  • Create input models and view models to be used solely by the UI.
  • Decorate your input models with data attributes for client-side validation.
  • Send commands from the UI to your backend to do business validation and persistence.
  • Send queries to your backend from the UI to get the data to show. Returned data should be placed in view models.
  • Use domain events to communicate between different bounded contexts

It does not necessarily require the backend logic to be put in an application server (although it is very desirable to enable having multiple UIs with the same backend). You can use in-memory events to send commands and queries too.

But again, look at what you really need, don’t try to overscale your abstractions just because the book says so. Remember that very often abstractions are put in place just because someone heard this is a good thing. Repositories is a classic example, when people say it makes their system persistence ignorant and they can change their ORM but in fact no one does that. When ORM is changed it means almost full redesign and repositories get scrapped equally well together with all other code.

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa

Validation and data persistence in a domain model

My (first and current) workplace (a .NET shop) suffers from an over-abundance of anemic domain models, to the extent that I don’t really know how validation and data persistence should be handled in a proper domain model.

Data Persistence

One option would be to give the domain model a way to do persistence itself. You could, for example, inject an IFooRepository via constructor injection, and have that resolved by an IoC container to ensure you don’t create a dependency on it (à la onion architecture). But I’m not sure if the code that uses the domain model should be responsible for calling methods to save the data, etc., or if it should be done implicitly behind the scenes on a background thread. Perhaps this breaks that purity of the domain model and is more along the lines of the active record pattern.

The other option I see is to not tie the domain model to data persistence at all and instead have a coordinating service layer responsible for that aspect.

What are the best practices for data persistence in the domain model pattern?

Validation

Another problem I don’t know how to solve with a proper domain model is how to indicate to the UI why the current model state is invalid without coupling to (or at least catering to) the UI. For example, let’s say I have a form an user fills out with various fields. We want to validate that input, and if something is wrong, indicate an error on that specific field with a message.

How would we handle validation with that level of granularity without adding significant complexity to the domain model, or doing hack-ish stringly-typed things (like throwing an validation exception with the property’s name and a message)?

I could be mistaken in my understanding, but I believe your trying to redesign your Domain Model so that it isn’t riddled with anemia. A couple of really, really great books on the matter are:

  • Martin Fowler – Patterns of Enterprise Application Architecture
  • Eric Evans: Domain-Driven Design: Tackling Complexity in the Heart Of Software
  • Vaughn Vernon: Implementing Domain Driven Design

They have a lot of content which answers quite a few questions on your goal. One of which is:

A rich Domain Model can look different from the database design, with
inheritance, strategies, and other Gang of Four patterns, and complex
webs of small interconnected objects. A rich Domain model is better
for more complex logic, but is harder to map to the database.

A simple Domain Model can use Active Record, whereas a rich Domain
Model requires a Data Mapper. Since the behavior of the business
subject to alot of change, it’s important to be able to modify, build,
and test this layer easily.

That is an excerpt from Fowler. He will go into details about the model being anemic and bloated models as well. The scope of the question to me appears quite large; so I’m not sure I could delve far into it. Those books should point you in the right direction; also will allow you to gauge your current project and implementation to refactor it quickly.

From a relatively basic understanding:

You should be able to abstract your model, which will allow a brief overlay of the UI and Data Access into your Domain Model. But otherwise the model should allow a clear, clean, concise implementation which will help separate responsibility.

Sorry I couldn’t be more help.

The question arises what your UI is using to get the data and how it sends the data to be persisted. I’m afraid since you mentioned you have no service layer and you suffer with finding the right place for your validation, that your UI works directly with your domain classes. That could be the way to go, however it does not sound like a very complex application and you can do persistance work and querying right in the UI code. You can check posts of Ayende Rahien and many others who talk about getting rid of repositories. In relatively simple scenarios ORM is capable to provide enough isolation of domain model from the persistance itself. Also it is a questionable matter if modern ORMs can be seen purely as DAL. Look at NHibernate, it can do so much more than just mapping simple tables to simple classes. And if you look at your repositories you might find a bunch of methods called GetByThis and GetByThat, which issue a simple query to the ORM (if you use one of course) and just play a silly role of unneeded abstraction to make an impression that you do DDD.

Concerning your comment about “not creating” dependencies by injecting repositories – you will onvert control but you will have dependency as soon as you use repository class instance in your domain object. It does not matter how it gets there. So this is the worse choice of all.

To your validation question I would recommend you to look closely to your validation as such and decide what validation is domain specific and what is more data entry specific. Data entry validation like mandatory fields should not be checked by the domain model. It is a simple job and UI layer is perfectly capable of doing that. Even more, most of modern UIs are able to do this validation very easily. However you need to find a way to inform your UI about the data input rules (I will get back to it below). Your domain model need to perform more business-oriented validation, like if customer with such name already exists. But you, again, cannot do this inside your domain class since you are unable to query existing data from there because it is not the domain object responsibility to care about anything outside of its own aggregate.

So if you want to go to deal DDD journey I would recommend you to look at CQRS principle. It is often bound to event sourcing but you can just skip that. Concentrate on this scenario, when using RDBMS with or without ORM or NoSQL for persistence:

  • Create input models and view models to be used solely by the UI.
  • Decorate your input models with data attributes for client-side validation.
  • Send commands from the UI to your backend to do business validation and persistence.
  • Send queries to your backend from the UI to get the data to show. Returned data should be placed in view models.
  • Use domain events to communicate between different bounded contexts

It does not necessarily require the backend logic to be put in an application server (although it is very desirable to enable having multiple UIs with the same backend). You can use in-memory events to send commands and queries too.

But again, look at what you really need, don’t try to overscale your abstractions just because the book says so. Remember that very often abstractions are put in place just because someone heard this is a good thing. Repositories is a classic example, when people say it makes their system persistence ignorant and they can change their ORM but in fact no one does that. When ORM is changed it means almost full redesign and repositories get scrapped equally well together with all other code.

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật