0

I'm wondering what the best approach is to take with validation.

If I have a complex object object composed of primitives, associations, and collections of other custom objects, should an IsValid() method validate the child objects as well as the required fields/keys of the root object?

If yes, should this be in some sort of abstract class, or is it best to use interfaces? With abstract, I would need to cast my child object interfaces to their concrete class definition in order to use an abstract method, whereas with interface validation I believe I can keep my children as interfaces as I call their validation methods.

Also, I'm not using MVC, but MVP with web forms (and trying to employ DDD principles).

Thanks.

UPDATE

I have a Aggregate root of ScheduledMeeting:

class ScheduledMeeting : BaseValidation
{
     ScheduledMeetingID {get;set;}
     ITimeSlot TimeSlot {get;set;}
     IList<IMeetingAssignee> Assignees{get;set;}
     DateTime meetingDate {get;set;}

     AssignEmployees(IList<IEmployees> employees){}
}

Currently, there exists an abstract class of BaseValidation, which looks similar to the following:

 public bool isValid(bool validateKeys)
    {
        if (validateKeys)
        {
            ValidateRequiredFields();
            ValidateKeys();
        }
        else
        {
            ValidateRequiredFields();
        }
        return true;
    }  

where ValidateRequiredFields() and ValidateKeys() are overridden in implementing objects.

If I'm to use the above and cascade to IMeetingAssigned, I would need to loop in both ValidateKeys() and ValidateRequiredKeys() in ScheduledMeeting, casting IMeetingAssigned to concrete MeetingAssigned before then calling either ValidateKeys() or ValidateRequiredKeys() in this object (as it would also implement BaseValidation), and so on, all the way down.

UPDATE 2

I am stuck with .NET 3.5, and so cannot implement Code Contracts, etc. (as far as I'm aware).

2 Answers 2

2

Don't let your objects get into an invalid state in the first place, saves you a lot of 'IsValid' trouble.

Sign up to request clarification or add additional context in comments.

3 Comments

+1 besides, validation is not always the same depending on the context. See lostechies.com/jimmybogard/2009/02/15/validation-in-a-ddd-world codebetter.com/gregyoung/2009/05/22/always-valid
Ok, are we talking about invariants here as well, as in [ContractInvariantMethod]?
+1. Don't use empty get/set properties. Always make sure that the objects is in a valid state. blog.gauffin.org/2012/06/protect-your-data
0

Since you're employing Domain Driven Design I assume you have identified and modelled your classes as Aggregates.

To answer your question: Yes, the Aggregate Root is responsible of making sure that itself and everything that's contained is valid at any given point in time. The Aggregate Root should never be in an invalid state.

Update from the comments: Get rid of your validation interface. An Aggregate should never be in an invalid state in the first place. Whenever the state of your AR is about to change, make sure the resulting state wouldn't brake any invariants. If it would, the AR should reject the modification.

Enforce the invariants, don't validate after the fact.

6 Comments

Hi - yes. I have an aggregate root (=>ScheduledMeeting, which has: TimeSlot value object, and List<IMeetingAssignee> and other fields which are primitives. So does this mean that child objects (of an aggregate root) shouldn't concern themselves with validation at all?
From an outside point of view the aggregate root is ultimately responsible of make sure to be in a valid state at any time. Internally it can delegate validation to it's parts or external services, of course. However, the premise should always be: Keep it as simple as possible.
So what would be the preferred method in this scenario then? As far as I can see, using an abstract class would mean you would need to be aware of the concrete implementation of the child classes in order to call the abstract is valid method. Interfaces bypass this need for the concrete casting, but have no shared behaviour. I'm not sure whether it's bad practice to have an Ivalidation interface whose methods are implemented by the abstract class -> meaning I would be using a combo of abstract and interface, with the two being coupled to an extent.
Get rid of your validation interface. An Aggregate should never be in an invalid state in the first place. Whenever the state of your AR is about to change, make sure the resulting state wouldn't brake any invariants. If it would, the AR should reject the modification.
But is this not just a change in when you call IsValid or CheckInvariants? In other words, I try to assign an employee to a ScheduledVisit, and at that point the ScheduledVisit Object would need to call CheckInvariants, and cascade down. So it's the same situation we're already trying to solve is it not? (unless I've misinterpreted).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.