Validation Block - Only DTO

Topics: Validation Application Block
Mar 3, 2009 at 12:24 AM

I am new to the Ent Lib Validation Block
It seems straight foreword to use, but I have a question that I could not find the answer to on this forum or searching on Google

Consider a simple Person Class:

public class Person
{
    int _personId;
    string _personName;

    public int PersonId{
        get{ return _personId;}
        set{_personId = value;}

    public string PersonName{
        get{ return _personName;}
        set{_personName= value;}
}

And consider that as Person Factory Class like so:

public class PersonFactory
{
    public static Person GetPerson(int personId)
    {
        ...implementation
    }
}

I want to apply the Validation Block with the following attribute:

[RangeValidator(0,RangeBoundaryType.Inclusive, 100,RangeBoundaryType.Exclusive, MessageTemplate="PersonId should be between 0 and 99", Ruleset="DefaultRuleset")]

The problem is that the person class is in my data layer - and is actually created using Entity Frameworks.  That means I can't easily apply the validation in the EF.  I want to apply this validation in my PersonFactory (true SOC - validate in the Domain Logic Layer, not the Data Layer) on the GetPerson Method's personId's parameter - but I don't think I can.  I have monkeyed around with it for a bit and I have not had any success.

My question - does the validation block only apply to DTO properties and not argument parameters?  If not, how do you apply against the method?



Mar 3, 2009 at 7:47 AM
Hi,

AFAIK, In the Validation Application Block it is only possible to validate parameter in the WCF Integration, see this: http://msdn.microsoft.com/en-us/library/dd140110.aspx . However, there are some possible work around found.

One is to explicitly validate the parameter:

public Person GetPersonById(int personId)

{

     RangeValidator rangeValidator = new RangeValidator(0, RangeBoundaryType.Inclusive, 100, RangeBoundaryType.Exclusive,

                "PersonId should be between 0 and 99", false);

     ValidationResults res = rV.Validate(personId);
     return null;

}

Another is to use the policy Injection and add a [ValidationCallHandler] to the Method and the Validator attributes to the parameters.

http://msdn.microsoft.com/en-us/library/cc309464.aspx

and invoke the method using the policy injection.


Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Mar 3, 2009 at 10:58 AM
Edited Mar 3, 2009 at 11:00 AM
Hi,

The understanding that I have of the validation block is that it simplifies business object validation and UI level validations and several appropriate techniques have been provided (like the ValidationProvider for UI, Attribute based Validator creation for business objects) to achieve the goal of  Validation Application Block. But you are attempting to provide validation for a object factory class which I dont think would be one of the appropriate usages of VAB. However, though you might find ways or workarounds to enforce validation in the factory, will it not be the same as implementing those validations physically there? Is the above referred code not the same as below - 

    public Person GetPersonById(int personId)
    {
        if ((personId < 1) || (personId > 99)) return null;
    }

I am not sure what added benefits you will get by using VAB here. I don't think you will have a statement like Validation.Validate(PersonFactoryObject) somewhere in your code. Then how do you plan to use benefits of VAB while using it on a factory class.

I may be wrong as I am also relatively new to Enterprise Library and VAB. However, this is my idea about your approach.

Mar 3, 2009 at 12:19 PM
Thanks for the responses

I am going to take Policy Injection for a spin around the block and see if that can do it.  I'll post back my results.
Mar 3, 2009 at 1:15 PM
Hi JamesDixon,

Have you considered a Business Logic Layer between the presentation and data layers?  Like you I'm new to EntLib 4.1 (started yesterday) and am traveling a similiar road using the CompositeWPF/Prism which is a multi-targeting platform (codebase that works on both Silverlight and Desktop).  

My knee-jerk reaction would be that Policy Injection would be best used for cross cutting concerns while the Business Logic Layer handle the validation and other business logic; which should work without regards to the data layer's Model, i.e., L2S, EF, etc. 

FYI,  http://www.CodePlex.com/SDMS is my open source project where I am evolving architecural concepts in case your interested.   Perhaps the most significant is the "single" configuration file (Web.Config) that manages all modules, layers within the Presentation and Middle Tiers (to ease enterprise application deployment)

PRESENTATION  TIER                     MIDDLE TIER                     DATA TIER

Silverlight -> BLL -> DAL     --->    WCF -> BLL -> DAL    --->  SQL Server 2008 (coming soon)