0

I'm using Entity Framework 6 and the repository pattern, with a service layer on top. In my POCO entity classes, I do use DataAnnotations for basic requirements such as KeyAttribute and RequiredAttribute. I perform business-specific validation in my service layer, though. So for example, my AccountService has an Insert method for inserting a new Account. I'll do checks like whether or not an account is eligible to be created based on some business rules, etc. If it's not eligible then I'll throw a validation exception there.

A problem that I'm trying to solve is what about when an existing Account is being updated? Where would I perform validation for changes to individual properties of Account? In my repository pattern implementation, I have a unit of work object which contains the DbContext and the unit of work class only exposes my individual services (which use that DbContext) as well as a single SaveChanges method, which just calls the DbContext's SaveChanges method. So, to update an existing Account, you would fetch it using the service layer, it'd be tracked by the DbContext and you'd edit the needed properties and call SaveChanges. There is no Edit method on my service that forces the user of my library to pass through that for validation.

Where should I perform this kind of validation?

Edit: I'd also be open to a way to make it so that some kind of Edit method is required, and that fetching existing entities does not track whem in the DbContext. I think this might complicate things such as lazy loading and stuff, though.

Ryan
  • 7,733
  • 10
  • 61
  • 106
  • When you have to go to the database then you need to use DbContext and DbContext has an Overridable method called ValidateEntity http://stackoverflow.com/a/19406993/150342 – Colin Jan 22 '14 at 22:54

1 Answers1

0

If you are already using DataAnnotations, look at implementing IValidatableObject

This will allow you to encapsulate the extended validation inside the class. There is an example of using it in this stackoverflow answer

Community
  • 1
  • 1
Trevor Pilley
  • 16,156
  • 5
  • 44
  • 60
  • Doesn't this move even more business logic into the POCO? I already feel like DataAnnotations are too much, which is why I try to do as much as possible inside my service layer. For example, now my entity classes will need to access my repositories for certain validation logic. If I were hacking together a quick prototype, I would definitely go this `IValidatableObject` route, but in my current case I'm trying to separate concerns as much as I can. – Ryan Jan 22 '14 at 21:24
  • Well either the entity should know how to validate its own data or you need to create a separate validator class which your service uses to validate an object prior to passing it to your repository – Trevor Pilley Jan 22 '14 at 21:26
  • Yea, that second scenario is exactly what I'm trying to solve, except for an existing entity from a repository. An entity has been fetched and modified, there is no method required to add it back to the repository other than calling `DbContext`'s `SaveChanges` method. I guess I could override that and perform validation in there. – Ryan Jan 22 '14 at 21:29
  • That's why I suggested IValidatableObject as it's part of DataAnnotations anyway so it should get invoked by the DbContext when it validates the object. – Trevor Pilley Jan 22 '14 at 21:38
  • I guess using `IValidatableObject` works pretty well for simple validation. Overriding `Validate` on my `DbContext` can be used for more complex validation, needing to hit the database. Although I dislike how my validation is now split up into 2 different areas, and neither ended being my service layer. :( – Ryan Jan 23 '14 at 03:00