Validating domain objects

They bind directly to the domain object from the user interface and need to make all of the properties public and settable, or they have their ORM configured to load the object through public setters, or they made wide use of object initializers on their domain objects.

The fact that these options were chosen doesn't make valid entities a fallacy, it just makes them hard to do given the other set of design choices (none of which, btw, are usually the best way to use tools like data binding and ORMs).

In real systems, there is complex logic that decides when an entity is valid for particular operations.

The notion that objects have state and behavior and that classes have invariants are key to making large complex systems work reliably.

I spend way too much time helping people fix bugs where the root cause ends up being "gee, that object should never have had those values".

That's OK, if all you want to do is hold data - but a data structure is not an entity/class! In this case the entity is not invalid since your UI will handle this case to propse your user to select a gender on next edit.

But there are things that should never happen in your entity: If there is no meaning for Joined Date and Last Login Date to be in reverse order, it's probably not a good idea to make it two independent properties.

Often you also have rules to determine what operation can be done according to the entity state [can I do this if the user as no gender ? But these are not validation rules even if they follow the same Specification pattern.

Pretty weak arguments for abandoning the underpinnings of two decades of object-oriented programming.

There are plenty of options to make it possible and clean.

In this case, you UI validation layer is responsible to submit valid data that will be accepted by your entity.

For instance, when loading historical data, some genders may be missing. The answer is certainly not to fail the query operation.

The dates in the User Profile class present the opportunity for some more complex business rules.

It returns a result that contains zero or more error codes.