How do I avoid duplicating validation logic between the domain and application layers? - validation

Any given entity in my domain model has several invariants that need be enforced -- a project's name must be at least 5 characters, a certain product must exist to be associated with the project, the due date must not be prior to the current date and time, etc.
Obviously I want the client to be able to display error messages related to validation, but I don't want to constantly maintain the validation rules between several different layers of the program -- for example, in the widget, the controller, the application service or command object, and the domain. Plus, it would seem that a descriptive error message is presentation-related and not belonging to the domain layer. How can I solve these dilemmas?

I would create specific exceptions related to your expected error conditions. This is standard for Exception handling in general and will help with your issue. For example:
public class ProjectNameNotLongEnoughException : System.Exception
or
public class DueDatePriorToCurrentDateException : System.Exception
Mark these possible exceptions in the xml comments for the methods that may throw them so that applications written against your domain model will know to watch out for these exceptions and will be able to present a message within the presentation of the application. This also allows you to have localized error messages based on the culture without cluttering up your domain model with presentation concerns.
If you choose to perform client-side validation, I'm afraid that you can't have your cake and eat it too. In this case, you may have to duplicate validation logic in order to achieve the desired features while maintaining your architecture.
Hope this helps!

I realise this is an old question, but this may help others in a similar situation.
You have here Behavior and Conditions which you need to encapsulate into your domain model.
For example, the ProjectName having a requirement on a certain length I would suggest should be encapsulated within a ValueObject. It may seem overboard for some, but within our Domain Model we almost always encapsulate native types, especially String, within a ValueObject. This then allows you to roll your validation within the constructor of the ValueObject.
Within the Constructor you can throw an Exception relating to the violation of the parameters passed in. Here is an example of one of our ValueObjects for a ZoneName:
public ZoneName(string name)
{
if (String.IsNullOrWhiteSpace(name))
{
throw new ArgumentNullException("Zone Name is required");
}
if (name.Length > 33)
{
throw new ArgumentException("Zone name should be less than 33 characters long");
}
Name = name;
}
Now consumers of that ValueObject can either perform their own validation before calling the constructor, or not, but either way your invariants will be consistent with your model design.
One way we build validation rules within your Domain Model, and then utilise them within your UI is to use the Mediatr module, which uses a One Model In, One Model Out pattern, and allows you to define Validators for each of your Query or Command models. These are defined using FluentValidation. You can then add a Provider to the ModelValidatorProviders within MVC. Take a look at JBogards ContosoUniversity example here https://github.com/jbogard/ContosoUniversity/tree/master/src/ContosoUniversity and look at the DependancyResolution folder, DefaultRegistry.cs.
Your other example of a Product must exist to be linked to a Project. This sounds to me like a Domain Service would be the best option to facilitate the cooperation between 2 bounded contexts? The Domain Service will ensure the invariants remain consistent across the bounded contexts. That Domain Service would not be exposed publically, so you would need an ApplicationService or a CQRS type interface which will take that DomainService as a dependency, allowing the DomainService to perform the operations required. The DomainService should contain the Domain Behavior, whereas the Application Service should just be a facilitator to call that function. Your DomainService would then throw exceptions rather than result in inconsistent or invalid invariants.
You should ultimately end up in a position where you don't have duplicated validation, or at least you never end up with invalid invariants because validation has not been performed at some point, as validation is always handled within your domain model.

While a descriptive error message may seem to pertain to presentation moreso than business, the descriptive error message actually embodies a business rule contained within the domain model -- and when throwing an exception of any kind, it is best practice to pass along some descriptive message. This message can be re-thrown up the layers to ultimately display to the user.
Now, when it comes to preemptive validation (such as a widget allowing the user to only type certain characters or select from a certain range of options) an entity might contain some constants or methods that return a dynamically-produced regular expression which may be utilized by a view model and in turn implemented by the widget.

Related

Creational adapter

I have a lot of code like this
additional_params = {
date_issued: pending.present? ? pending.date_issued : Time.current,
gift_status: status,
date_played: status == "Opened" ? Chronic.parse("now") : (opened.present? ? opened.date_played : nil),
email_template: service&.email_template,
email_text: service&.email_text,
email_subject: service&.email_subject,
label: service&.label,
vendor_confirmation_code: service&.vendor_confirmation_code
}
SomeService.new(reward, employee: employee, **additional_params).create
The same pattern applies to many models and services.
What is the name of this pattern?
How to refactor the current solution?
Is there a gem to solve this kind of solution? Like draper or something else
To me, that looks a bit like a god object for every type of entity. You expect your service to take care of everything related to your entity. The entity itself just acts as a data container and isn't responsible for its data. That's called an anemic model.
First of all, you need to understand that there can be several representations of the same entity. You can have several different classes that represent a user. On the "List user" page, the class contains just a subset of the information, maybe combined with information from the account system (last login, login attempt etc). On the user registration page, you have another class as it's not valid to supply all information for the user.
Those classes are called data transfer objects. Their purpose is to provide the information required for a specific use case and to decouple the internal entity from the external API (i.e. the web page).
Once you have done that, your service classes will start to shrink and you need fewer custom parameters for every method call.
Now your service class has two responsibilities: To manage all entities and to be responsible for their business rules.
To solve that, you should start to only modify your entities through behaviors (methods) and never update the fields directly. When you do so, you will automatically move logic from your service class to your entity class.
Once that is done, your service classes will be even cleaner.
You can read about Domain Driven Design to get inspired (no need to use DDD, but get inspired by how the application layer is structured in it).
You can try the builder pattern. I am not familiar with a ruby gem, but you can find information here: https://en.wikipedia.org/wiki/Builder_pattern and https://en.wikipedia.org/wiki/Fluent_interface

DDD Entity validation

I have a question related to entity validation. As an example, there is a User which can be registered into a system given email and password. The business rule says that:
email must be valid (must conform to email format) and unique;
password should be between 6 and 20 characters.
My initial thought is to place the validation inside the User.Register(email, password). The main advantage of this approach is that User controls how it is registered by verifying itself the correctness of registration data. The disadvantage is that email uniqueness verification requires calls to UserRepository, so the User might have dependency on its Repository. To solve this issue, email and password validation might be factored out to some kind of BusinessRule objects. So the validation in User.Register() method might look like this:
var emailValidationErrors = _emailRule.Validate(email);
var passwordValidationErrors = _passwordRule.Validate(password);
where _emailRule and _passwordRule might be passed as constructor arguments: User(EmailRule emailRule, PasswordRule passwordRule).
In this casse User is not directly coupled to UserRepository. In this way the rules are explicitly shown in the domain, which make it more expressive.
So the question is: what do you think about this approach? Are there any other solutions?
You could implement a Domain Service that encapsulates this. Typically in DDD you would use a Domain Service when the business logic falls outside of the scope of one individual aggregate; in this case it is the uniqueness check. So, what I'd do is:
public class UserRegistrationService : IUserRegistrationService
{
private readonly IUserRespository _userRepository;
public void Register(string email, string password)
{
if (!_userRepository.DoesEmailExist(email))
throw new Exception("Email already registered");
User user = User.Create(email, password);
_userRepository.Save(user);
}
}
Also, if you are worried about User.Create being called outside of the registration service and therefore escaping the uniqueness check, you could possibly set the User.Create method to internal, meaning the only way to create a user is via the RegistrationService.
There are three validations that you're trying to do in this example:
Email address must be a valid format;
Email address must be unique (i.e., there isn't an existing user who has that email address);
Password must conform to certain length constraints.
1 and 3 above are simple validations that should be able to be done declaratively on the entity properties (using custom attributes and a suitable validation library in .NET for example).
2 above is the tricky bit, and that's where the intrinsic dependency on the User repository exists in my opinion.
The question is: "Does the responsibility of preventing the creation of a User with the same email address as an existing User lie with the User entity?". I believe the answer to that question is "No" ... it "feels" like this responsibility should lie with a higher-level service or entity for which it is natural to have knowledge of the whole set of users.
So, my take is:
Place those validations that sit with the user inside the User entity (strong cohesion);
Place the uniqueness constraint in a DDD service that is specifically responsible for maintaining the invariants of the set of users--it would do this by wrapping the uniqueness check and the persistence of the new User in a transaction.
You can kind of think there are 2 kinds of validation: internal state validation, and context validation. You can perform internal validation from within that entity, and then perform context validation using some service.
Markus,
His approach was not bad, but I just do differently.
In my opinion you respect the OCP, putting validation rules out of the Entity, which was wisely decided. Using these validation rules in the class constructor you are suggesting that the rules are immutable, right?
I would not do this way, just create a method dyad setting the rules as this constructor. For me it was not clear what would happen if the validation rules were violated. I like to throw exceptions to the user interface that handles as more ubiquitous warnings.
Another thing that was not clear to me is the event that triggers this validation. it would be when the entity User was added to the repository or have a method of the entity that would do this? I'll take the second option calling the method isValidAuthentication() throwing that exceptions.
Regarding the dependence of the Entity to the Repository, I venture to say that is wrong. You could even make the entity dependent on him, because the repository is a collection of objects, what's wrong with this? However, at this point seems clear that validation is a Service. So if we put these validations in a Service would eliminate this coupling and apply the OCP again. Do you agree?
A big hug and success!

Validation with DDD in SOA application using IoC

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?
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.
You have two types of validation:
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.
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.

Validation on domain entities along with MVP

How do you apply validation in an MVP/domain environment ?
Let me clearify with an example:
Domain entity:
class Customer
{
string Name;
etc.
}
MVP-model
class CustomerModel
{
string Name;
etc.
}
I want to apply validation on my domain entities but the MVP model has it's own model/class
apart from the domain entity, does that mean I have to copy the validation code
to also work on the MVP-model?
One solution I came up with is to drop the MVP-model and use the domain entity as MVP-Model,
but I don't want to set data to the entities that isn't validated yet.
And second problem that rises is that if the entity has notify-events,
other parts of the application will be affected with faulty data.
A third thing with that approach is if the user edits some data and then cancels the edit, how do I revert to the old values ? (The entity might not come from a DB so reloading the entity is't possible in all cases).
Another solution is to make some sort of copy/clone of the entity in question and use the copy as MVP-model, but then it might get troublesome if the entity has a large object graph.
Anyone has some tips about these problems?
Constraining something like the name of a person probably does not rightfully belong in the domain model, unless in the client's company there is actually a rule that they don't do business with customers whose names exceed 96 characters.
String length and the like are not concerns of the domain -- two different applications employing the same model could have different requirements, depending on the UI, persistence constraints, and use cases.
On the one hand, you want to be sure that your model of a person is complete and accurate, but consider the "real world" person you are modeling. There are no rules about length and no logical corollary to "oops, there was a problem trying to give this person a name." A person just has a name, so I'd argue that it is the responsibility of the presenter to validate what the user enters before populating the domain model, because the format of the data is a concern of the application moreso than the domain.
Furthermore, as Udi Dahan explains in his article, Employing the Domain Model Pattern, we use the domain model pattern to encapsulate rules that are subject to change. That a person should not a have a null name is not a requirement that is likely ever to change.
I might consider using Debug.Assert() in the domain entity just for an added layer of protection through integration and/or manual testing, if I was really concerned about a null name sneaking in, but something like length, again, doesn't belong there.
Don't use your domain entities directly -- keep that presentation layer; you're going to need it. You laid out three very real problems with using entities directly (I think Udi Dahan's article touches on this as well).
Your domain model should not acquiesce to the needs of the application, and soon enough your UI is going to need an event or collection filter that you're just going to have to stick into that entity. Let the presentation layer serve as the adapter instead and each layer will be able to maintain its integrity.
Let me be clear that the domain model does not have to be devoid of validation, but the validation that it contains should be domain-specific. For example, when attempting to give someone a pay raise, there may be a requirement that no raise can be awarded within 6 months of the last one so you'd need to validate the effective date of the raise. This is a business rule, is subject to change, and absolutely belongs in the domain model.

What is the best way to handle domain-centric validation while providing a rich UI experience?

My company is developing a GUI application that allows users to query a legacy database system and have the results displayed back to them on the screen (the results just come back in a blob of plain-text). I'm struggling with the best way to structure the interaction between the user interface and the domain layer, especially validation of user input.
Basic Use Case
User selects a query to run from a menu in the application.
The application code displays the data entry form for the selected query.
The user enters the parameters for the query. If a field contains invalid data, it is immediately highlighted in red, and its tooltip text is changed to display an error message (i.e. if you are entering a Person query, and you enter a date of birth in the future, for example, the date of birth field will immediately turn red).
When the user clicks Run Query, the application runs a second validation pass; this second validation pass is required in order to run validation checks that involve multiple fields. If the this validation check passes, and all the fields are valid, the query is sent; otherwise, the user is prompted to fix any remaining errors.
My Current Validation/Error Reporting Strategy
Currently, I'm using domain-centric validation, but the overall design seems messy to me and maybe a little too over-engineered. A brief overview of the current design:
Domain layer: I have one class per query. Every query class contains a collection of IQueryField objects that hold the values entered by the user. Each query class implements a common IQueryMessage interface, which defines (among other things) a Validate method. This method is called to enforce message-level validation rules (i.e. rules that must examine the state of multiple fields at once). The IQueryField interface also defines a 'Valdate' method (among other things). This is to support per-field validation rules.
Per-field validation: To handle the per-field validation and error reporting, the data entry code binds each input control to an IQueryField; whenever the user changes the value of a control, it calls the the corresponding IQueryField's Validate method, which in turn fills a Notification object (just a collection of strings at the moment) with any errors detected in the value entered by the user. The user interface code then checks the Notification object and changes the appearance of the user control to indicate an error condition, if necessary.
Message-level validation: When the user tries to send a query, the application calls the Validate method on the IQueryMessage instance associated with the data entry form (at this point, the data binding code has also ensured all the message's fields have been populated from the input controls on the form, and the per-field validation code has been run). If there are any validation errors, the user interface displays them at the top of the form. If there are no errors, the data entry form is closed and the query is serialized and sent over the network.
Is Something Wrong Here?
I feel like something isn't "right" here. I have a few issues with the current design:
I would like the domain-level validation code to indicate the name of any fields that are in error, bur I don't want to hard-code the UI label captions into the domain classes. One possibility I thought of was to have the domain-level Validate methods generate messages with a field placeholder, such as "%s cannot be in the future", and have the UI code fill in the placeholder with the correct label.
The IQueryMessage and IQueryField interfaces both have a method called Validate. I'm thinking this should be extracted into a separate interface, (IValidatable perhaps), but I wonder if I am making things needlessly complex.
I'm using VB6, so I can't use inheritance in my classes (VB6 supports classes but not inheritance). I can only define and implement interfaces. Because of this, and because of the way my current interfaces are designed, I'm duplicating a lot of boiler-plate code in my implementation classes. I am thinking of solving this with an inversion-of-control approach. For example, I was thinking of defining a single concrete QueryField class, which could be initialized with a collection of IValidationRule instances that define what validation rules to use, then the QueryField.Validate() method would just collect the results of executing each rule. This way, the validation rules can be tailored to each field, but the QueryField class can handle all the common field-related stuff (field name, field length, required/not required checks, etc.).
How Can I Improve This?
I'm interested in any refactoring suggestions and hints on improving the current design. Also, I'm not necessary tied down to domain-centric validation; other suggestions are welcome. The main motivation behind using domain-centric validation was to keep increase encapsulation, and allow query message and field objects to be used in a non-GUI environment, without having to rewrite all the validation logic.
When you initialize a QueryField object, pass a label to it from the GUI. Then it's the UI that is responsible for setting the label name which seems reasonable to me.
I don't think this is necessary.
What you are describing doesn't really sound like IoC but rather just plain old composition. Since you can't even use inheritance this improvement seems to make sense. Generally you want to prefer composition to inheritance anyways. However if you are almost done with the work then I wouldn't bother refactoring this late in the game.

Resources