As far as I understand a callback is a constraint that you can customise and set to any field for any type of validation.
A custom validation constraint overrides the base constraint class (creating any type of validation on any field)
I'm just not sure what the difference is, why would I use one and not the other?
Are there any performance differences too?
I haven't researched the Form Component that much to be aware of any performance differences, but besides that, why you should choose one over the other:
Callbacks
It is meant to customize the whole validation process, not just the Constraint. For instance, you can set where the error needs to be displayed;
The target is always a class, you can't use it on a property;
You can't reuse it, it is only available on that class/entity.
Custom Validator Constraints
You can reuse it everywhere (as said by #MrGlass, you can even use services as constraint);
It can be used on a class and property target;
You can only customize when something fails, not what is done after it fails.
Related
I've heard about different ways to write validation for domain models, So I want to know which of them is better in the domain-driven-design.
Some people say that it's better to validate the domain model's data before initializing it (it means that validations should be run on the related DTOs).
Some people say that it's better to validate the domain model's data after initializing it (it means that validations should be run on the initialized entity or domain model).
Also, some people say that all the validations should be run inside of the entity (exactly in setters or constructors)
Indeed, I was used to writing a combination of the above validations, but now I'm not sure about that. Which of them is common and basically more sensible?
In domain driven design, what you are most likely to see are "value objects" that guarantee certain constraints are met during initialization, therefore in the constructor of the value object itself. Since values are (by convention) immutable over their lifetime, you wouldn't normally include setters in their interface.
DTOs serve a different purpose, but are mechanically similar to value objects in many ways. So you might see validation in the DTO in addition to validation within the domain model.
You don't normally have value validation in your entities. An entity is typically holds references to values (which validate themselves) or other local entities (validated elsewhere), so checking that the references are correct is in bounds (ie, check for null).
I have a domain class which gets updated from the UI. It was some constraints to enforce that the users fill in all the required information and all is well.
However, I also have some quartz jobs which update the domain and they do not necessarily need to adhere to all those constraints. I'd like to ignore specific ones so that save() works.
There are a couple of ways I can think of doing this:
Use save(validate: false) but then that will ignore all the constraints (not exactly what I want)
Remove the constraints which only apply to the UI and manually check that the data is valid in the controller
Wrap these constraints into validators which only kick in if the value of a transient property is saveFromUI (set this transient property from the controller before save())
These all seems as hacks. Any other (better) ways?
Almost sounds like you need to consider using a command object.
However, you can always specify which properties to validate in your case of update. So something like this:
myDomainInstance.validate(['prop1', 'prop2'])
...
myDomainInstance.save(validate: false) // since you already have done so manually prior to this.
The documentation has more information about validation.
As far as I can see, the validation within Entity Framework is built entirely around the assumption that, if an item fails its validation, it must not be persisted to the database. Is there any mechanism, possibly running parallel to normal validation, of making a constraint on a field produce a warning to the user, rather than an error which prevents the record from being saved/updated?
To be more specific, I have a situation where a particular numerical field has limits on it, but these are advisory rather than hard-and-fast. If the user enters a value outside these limits, they should get a warning, but should still be able to save the record.
In theory, I could subclass the ValidationResult class to make, say, a ValidationWarning class, then create a custom subclass of ValidationResults whose IsValid property was sensitive to the presence of ValidationWarning messages, and ignored them in deciding whether the entity is valid. However, this requirement has arisen in a project which is already someway along in its development, and it would require a lot of refactoring to make this kind of custom subclassing work properly. I would prefer to find a mechanism which could be levered in without creating that much disruption/rework.
I had a similar requirement on a project and how I solved it was this. If (ModelState.IsValid) is false, I cleared out the errors out of the ModelState and sent it on its way again,then logged the "error" to another service. This is a bit of a hack and I would'nt recommend doing as it is not exactly best practice.
I'm using ASP.NET MVC3 and i'm wondering that the default modelbinder binds to public properties but not to public fields.
Normally i just define the model classes with properties but sometimes i use some predefined classes which contains some fields. And everytime i have to debug and remember that the modelbinder just don't like fields.
The question: Whats the reason behind it?
but sometimes i use some predefined classes which contains some fields
While I cannot answer your question about the exact reason why the default model binder works only with properties (my guess is that it respects better encapsulation this way and avoids modifying internal state of the object which is what fields represent) I can say that what you call predefined classes should normally be view models. You should always use view models to and from your controller actions. Those view models are classes that are specifically defined to meet the requirements of the given view.
So back to the main point: fields are supposed to be modified only from within the given class. They should not be accessed directly from the outside. They represent and hold internal state of the class. Properties on the other hand is what should be exposed to the outside world. Imagine that in the property getter/setter you had some custom logic. By modifying directly the field this custom logic would be broken and potentially bring the object into an inconsistent state.
Maybe the reason for ignoring fields is to increase performance of the binder. Instead of searching all the Fields and properties. The Model Binder search for Properties only.
Though I think the Model Binder use cache to improve performance.
DefaultModelBinder exposes a public method:
DefaultModelBinder.BindModel, and a number of protected method available for overriding. All of them listed here.
Besides the model, these method refer to properties only, not fields, like
GetModelProperties,
GetFilteredModelProperties,
GetPropertyValue,
OnXYZValidating,
OnXYZValidated,
OnXYZUpdating,
OnXYZUpdated,
GetXYZValue,
where XYZ stands for either Model, or Property/ies, or both, and so on.
As you can see there is no Fields mentioned with these names whatsoever. As Darin explained no direct changes to Model's state are tolerated by the Binder. Hence no Field in its methods.
And also, you may wish to take a look at another important class: ModelBindingContext. An instance of this class gets passed to the BindModel, and subsequently to BindSimpleModel, and BindComplexModel, depending on model type (string, int,... are considered simple, everything else is complex).
So, this context has the following properties:
ModelXYZ, and
PropertyXYZ.
In other words you have no means to reference the fields in your ViewModel unless you do not override these classes and undertake special actions to do so.
But again, beware of fighting the framework, its always easier to follow it instead.
EDIT: The ModelMetadata class holds all the data needed to bind the model. Its code however, shows no sign of fields, field names, etc. Only properties are referenced and accessed. So, even if you try to inherit and override DefaultModelBinder and ModelBinderContext, you still won't be able to access fiellds, nevermind what their access modifier is: public, private, etc.
Hope this explains most of it.
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.