5

In my service facade layer, I have a service class with a method/operation that accepts a DTO (data contract) object. AutoMapper is used to map this DTO into an instance of my domain object to apply any changes. The request is passed onto my domain service which does the actual work. Here's what the method might look like:

public EntityContract AddEntity(EntityContract requestContract)
{
    var entity = Mapper.Map<EntityContract, Entity>(requestContract);

    var updatedEntity = Service.AddEntity(entity);

    var responseContract = Mapper.Map<Entity, EntityContract>(updatedEntity);

    return responseContract;
}

The Service and Mapper properties are set using constructor injection with Unity as the IoC container.

In performing the operation, the domain service makes changes to the entity then uses a repository to persist the changes like:

public Entity AddEntity(Entity entity)
{
    // Make changes to entity

    Repository.Add(entity);

    // Prepare return value
}

The Repository is also set using constructor injection.

The issue is that the data becomes immediately available to other clients once it has been persisted so I have to ensure that no invalid data is persisted. I've read the "blue book" of DDD (Evans) as well as Nilsson and am not clear what approach to validation I should take.

If my goal is to prevent the entity from entering an invalid state, should I validate entityContract in my service method to ensure all rules are satisfied before ever passing the request on to my domain service? I hesitate to do so because it seems like I'm breaking encapsulation having these rules defined in the service facade.

The reason we are using a thin facade layer delegating to domain services is that we are exposing course-grained interfaces in our API but support reuse via composition of the fine-grained domain services. Keeping in mind that multiple facade services may be calling the same domain service method, perhaps delegating these rules into the domain service would be better so we know every use is validated. Or should I validate in both places?

I could also put guards in the property setters that prevent unacceptable values from ever putting the entity into an invalid state. This would mean that AutoMapper would fail when trying to map an invalid value. However, it doesn't help when no value is mapped.

I still can't get past the thinking that these rules are part of the entity's behavior and determining if the object is valid should be encapsulated within the entity. Is this wrong?

So first I need to determine when and where I perform these validation checks. Then I need to figure out how to implement with DI so the dependencies are decoupled.

What suggestions can you provide?

SonOfPirate
  • 5,642
  • 3
  • 41
  • 97

2 Answers2

4

I've read the "blue book" of DDD (Evans) as well as Nilsson and am not clear what approach to validation I should take.

Blue book approaches the problem from a different angle. I think that the term 'Validation' is not used because it is a dangerous overgeneralization. A better approach is to think about object invariants, not validation. Objects (not only in DDD) should enforce their internal invariants themselves. It is not UI or services or contracts or mappers or 'validation frameworks' or anything else that is external to the objects. Invariants are enforced internally. You may find these answers helpfull: 1, 2, 3, 4.

I could also put guards in the property setters that prevent unacceptable values from ever putting the entity into an invalid state. This would mean that AutoMapper would fail when trying to map an invalid value.

You probably should not care about AutoMapper failing or using AutoMapper at all. Domain objects should encapsulate and enforce their internal invariants and throw exception if the attempt to break it is made. It is very simple and you should not compromise the simplicity and expressiveness of your domain objects because of some infrastructural issues. The goal of DDD is not to satisfy AutoMapper's or any other framework's requirements. If the framework does not work with your domain objects don't use it.

Community
  • 1
  • 1
Dmitry
  • 17,078
  • 2
  • 44
  • 70
  • The links are great. It's clear to me now that the interactive-type of validation that allows the object to go into an invalid state and provides a list of errors (via IDataErrorInfo, for instance) belongs in the UI/Presentation layer (ViewModel). And I'm good with putting guards in my domain objects to prevent them from going into an invalid state. But are you advocating against also putting checks in the service and/or facade layer unless they span multiple entities/aggregates? – SonOfPirate Sep 28 '11 at 16:32
  • 1
    You can put additional checking into services and UI as needed. My point is that domain objects should not rely on these checks. – Dmitry Sep 28 '11 at 16:35
  • @SonOfPirate - Just as a matter of interest, I use CodeContracts to enforce invariants in my domain objects. – RobertMS Jun 28 '12 at 14:26
1

You have two types of validation:

  1. Object consistency: is the responsibility of entities. Entities should not allow you to set them to invalid state, dependencies should be enforced, values should be in range. you have to design classes' methods and properties and constructors not to allow invalid state.

  2. Business roles validation: this type of validation requires server processing, like checking id availability, email uniqueness and the so. these types of validations should be processed in server as Validators or Specifications before persistence.

Mohamed Abed
  • 5,025
  • 22
  • 31
  • 3
    I offer that there is a third: UI validation. This is intended to provide interactive feedback to the user. I think this is where more of the validation frameworks (like Data Annotations and Enterprise Library) are targetted rather than implementing the other two types. – SonOfPirate Sep 28 '11 at 16:29
  • 1
    Yes you are right, I just concentrated on the validation of the domain layer, there is also a validation in UI which would be handeled in view models or presentation model using any UI compatible validation framework – Mohamed Abed Sep 28 '11 at 17:05
  • i agree with you must have a self validating domain. do you inject some validators into the domain objects for complex (business rules) validations? and do you have basic validations in the application layer for the commands(DTOs)? – danfromisrael Jul 10 '15 at 05:37
  • Yes I do inject some validators into domain when it is genuine domain validation and maintain correctness of domain where you can not have domain object in an inconsistent state. For app layer it is kind of optional to do validation if you want to show user friendly validation messages to UI or handle workflow based validation. – Mohamed Abed Jul 10 '15 at 10:05