1

I am developing an n-layer app. One of the layer is the BusinessLayer and consumes a set of POCOs defined in the CoreLayer. Also I have a PresentationLayer (WinForms)

CoreLayer

  • POCOs (classes with properties)
  • Repository interfaces (use the POCOs as parameters types) For example :

    public interfaces ICarRepository
    {
     IEnumerable<CarPOCO> GetAllCars();
    }
    
    public class CarPOCO
    {
      public int Id{get;set;}
      public string Name{get;set;}
    }
    

DataAccessLayer

  • Custom implementation of IRepositories. For example with SQLServer data access.

PresentationLayer

  • Contains all the WinForms to retrieve information=> generating POCOs and ideally I want to validate the user input. These POCOs are latter stored in DB

BusinessLayer:

  • Businnes logic
  • I want put the validation of the POCOs data here, but I am not sure if is the right place, or how to deal with it since they are defined in CoreLayer.

Questions

A. Where can I place the validation?

B. In which layer?And how(design) can I enrich the POCOs defined in CoreLayer with that validatons ?(I guess validation fits better in businesslayer since they represent business rules)

C. Can you show me a design pattern/some design guidelines for including that valdiations?

Many thanks, you are saving my day.

2 Answers 2

6

A. Where can I place the validation?

Regardless of your design there are two places where validation code goes:

  1. Near input
  2. Near use

You put validation near input so that you can show the user the mistake quickly and get a correction timely. Also so that you understand the users context well.

You put validation near use to protect against the many wild and wonderful things that can change data since it was first validated.

In some designs these two places are the same place. That can be fine until the application grows.

Understand that validation is required only when the type system is not specific enough for your needs. If a method can use any int then then no validation beyond the type system is needed. If a method can use any non-negative int then you need validation if your language doesn't have unsigned int.

B. In which layer?And how(design) can I enrich the POCOs defined in CoreLayer with that validatons ?(I guess validation fits better in businesslayer since they represent business rules)

Not all validation is a business rule. Sometimes it's an application rule. For example if the business doesn't care if Car ID is negative but your application does, maybe because of the DB, then it's not the business that created this rule. That's OK. It's still important to validate. But it's not a business rule.

PresentationLayer

Contains all the WinForms to retrieve information=> generating POCOs and ideally I want to validate the user input. These POCOs are latter stored in DB

It looks like the presentation layer generates the Car. We could enforce the ID's are positive rule here simply by never creating a negative or zero ID. However, because Id has a public setter anything that touches a Car can mess with it. If you changed that to private, switched to using a constructor to set ID it would be immutable and we'd never have to check it again. If you did that you could put the validation in the Car class itself. It becomes part of the Car type. If you don't then you'll want to check this again before putting it in the DB.

The Name could have a genuine business rule like "no swear words". This is likely user entered. You'd want to inform the user of the problem on the same screen they entered the swear word. Again you could switch to using using a constructor to set an immutable name and all objects of type Car would have swear free names. Otherwise you'll want to be sure to check this again before using it to be sure something else hasn't messed with it.

The presentation layer will need to handle validation failures if only to recover from them. Likely by telling the user "that won't work because ___, try again". It may delegate validation logic to a type or a rule that lives elsewhere but here is where it gets fixed.

DataAccessLayer

Custom implementation of IRepositories. For example with SQLServer data access.

If one of the peculiarities of your SQLServer is that it doesn't like negative ID's this would be a good place to double check that you aren't about to send one. If the DB is well behaved and produces its own error nicely you might not even need to check here. If it locks up or takes forever to produce the error you might want to stop trouble here. Now sure, we checked this before but at this point do you know where your Car object has been?

C. Can you show me a design pattern/some design guidelines for including that validations?

My favorite coding style only allows constructors to do two things: set state and validate state. If the object is immutable that's the last time state needs validation. Do that and you can lean on the type system to ensure validation.

Otherwise, just assume things are dirty whether or not they come directly from the end user. Don't assume it's been checked before because the system should be flexible, it should allow change, you're making a rigid system if you only work correctly when you get your Car objects from the presentation layer.

BusinessLayer:

Businnes logic I want put the validation of the POCOs data here, but I am not sure if is the right place, or how to deal with it since they are defined in CoreLayer.

This is a good place for the logic to live. This doesn't necessarily represent when the checks should happen since where and when can be decoupled. That will depend on your design.

Validation is extremely important to get right. Miss it and the results can be catastrophic. Push it to far into the wrong places and the system turns into cement. Use it wisely and you'll be on your way to making a flexible system that gracefully handles whatever is thrown at it.

8
  • Many thanks, so , following my design, in which layer will you put the validations?
    – X.Otano
    Commented May 30, 2018 at 15:05
  • 2
    @Badulake: It seems that you missed his point. You would put it in the layers that are closest to input and use. Which layers are those in your application? Commented May 30, 2018 at 15:18
  • @Badulake better? Commented May 31, 2018 at 11:06
  • @candied_orange yes,How can I deal with the validations of business rules and validations of database restrictions with success??Where I place them and how I could handle them? I have no idea how to handle that a objet is valid from the business point of view , but invalid to the database .
    – X.Otano
    Commented May 31, 2018 at 14:40
  • @Badulake: Might I suggest that you handle database restrictions in your data access layer, and business rules in your business logic layer? I'm wondering why you're having trouble working this out. Commented May 31, 2018 at 14:58
0

How can I add [my validation functionality] splitted in two layers for the same class, in a well-designed way?

In C#, you have a few choices. You can:

  1. Create a partial class to contain the validations. This is useful if your POCOS are being code-generated.

  2. Create a new class containing the validations and map the POCO to the new class in your other layer.

  3. Use a validation framework.

Personally, I'd just add an IsValid property to your POCO.

2
  • Ok...that sounds good. Why you add Isvalid property? For setting the getter to different rules depending of the layer?
    – X.Otano
    Commented May 31, 2018 at 15:34
  • Because that seemed like a good thing to name it. It's probably a bool property. Commented May 31, 2018 at 15:37

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.