ParameterValidatorFactory && ValidatorComposition

Topics: Validation Application Block
Apr 15, 2009 at 4:20 PM
Can somebody enlightme if is possible to hava a ValidatorComposition like this:

public void DummyMethod(
         [ValidatorComposition(CompositionType.Or)]
                                        [NotNullValidator(Negated=false)] 
                                        [NotNullValidator(Negated=true)] 
                                        object x
                                     )

and then validate like this:

Validator v = ParameterValidatorFactory.CreateValidator(p);
ValidationResults r = v.Validate(obj);

if it is possible the r.IsValid must be every time True, but is false...

maybe somebody can helpme....Thanks
Apr 16, 2009 at 3:51 AM
It is possible, I don't get though why you need it to be like that.  Anyway, if you're validating parameters, why do you still include codes for creating the validator?  In addition, if you're not using it in a WCF service, parameter validation would only work with the use of PIAB/unity using call handlers.  If your DummyMethod is within a class which implements an interface or derives from the MarshalByRefObject class, you should decorate it with the [ValidationCallHandler()] attribute. 


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com
Apr 16, 2009 at 8:55 AM
First thanks for the reply.

the idea is to resume the classic method parameter validation (if(x>1) then throw new Exception bla bla bla) with declarative information specified on the attributes and using the facade ParameterFactory
to get the validation results. It is simplier and a more reusable manner manage validation, at least i think so.

Can i have your opinion on that...Thanks


Apr 16, 2009 at 9:15 AM
So the ParameterValidatorFactory would create a validator based on the attributes you included in the parameter?  I don't see how are you going to do that but even if you did, I'm not sure it's a best practice approach.  The closest approach to yours that I could think of right now is to create a helper class that will validate your parameter based on a list of validators you passed.  Those validators however are not going to be placed as attributes but created within the method. 

public void DummyMethod(object x)
{
    //declare list of validators
    //create and add the validators you want to your list
    //pass the list to a helper class that performs the validation
}


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com
Apr 16, 2009 at 10:13 AM
I will try to defent my idea. Make your self conformatable to defend yours :)

when you sugest to use a helper class to make validation i think on my current validation algoritms. what i'm doing with a helper class is
having validation method count equal to methods declaration, or at least on the same number order. Imagine that you have 50 methods and 
all require validation, then you must have 50 validation methods on the worst case. Thinking optimist you can reuse some validation methods
 (using some architecture or reusing same validation methods), but you will end with a regid validation declaration.

Using what i sugested easily you mantain the validation properties (because their all attributes and just looking at method signature you see 
whats going on) and reuse the custom or built-in validators on the application block. The disavantage it's that the ParameterFactory facade use 
reflection to get the ParameterInfo stuff.

Sorry for my Portuguese English :).
Apr 20, 2009 at 1:28 AM

In my opinion, although indeed you can readily see the validation logic in just a look, adding validator attributes to parameters is also a form or rigid validation declaration, .  Sorry if I still don't understand the context of how you want to take advantage parameter validation here specially the part on how are you going to "reuse the custom or built-in validators on the application block".


Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com

Jun 25, 2010 at 3:49 AM

i have resolve this problem.

you can validate it in callhandler.

 

public interface IOutput
    {
        void Output([StringLengthValidator(5, 10)] string x);
    }
  
    [MyHandler ]
    public class OutputImplement1 : IOutput
    {
        #region IOutput Members

        public void Output([StringLengthValidator (5,10)] string x)
        {
            throw new Exception();
            Console.WriteLine("output : {0}", x);
        }

        #endregion
    }

 public class MyHandler : ICallHandler
    {
        #region ICallHandler Members

        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            IMethodReturn retvalue = null;
            Console.WriteLine("方法名: {0} ", input.MethodBase.Name);
            Console.WriteLine("参数:");

            #region 验证参数
            Validator validator = ParameterValidatorFactory.CreateValidator(input.Arguments.GetParameterInfo(0));
            ValidationResults vrs= validator.Validate(input.Arguments[0]);

            #endregion

            for (var i = 0; i < input.Arguments.Count; i++)
            {
                Console.WriteLine("{0}: {1}", input.Arguments.ParameterName(i), input.Arguments[i]);
            }
            Console.WriteLine("执行");

            retvalue = getNext()(input, getNext);

            if (retvalue.Exception != null)
            {
                Console.WriteLine("出现异常");
                try {

                }
                catch (Exception ex)
                {
                }

            }
            else
            {
                Console.WriteLine("正常结束");
            }
            return retvalue;
        }

        public int Order
        {
            get;
            set;
        }

        #endregion
    }
    public class MyHandlerAttribute : HandlerAttribute
    {
        public override ICallHandler CreateHandler(IUnityContainer container)
        {
            return new MyHandler();
        }
    }

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.ObjectBuilder2;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.InterceptionExtension;
using Microsoft.Practices.EnterpriseLibrary.Common;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.PolicyInjection;

namespace UnityAOP.Main
{
    class Program
    {
        static void Main(string[] args)
        {      
            var container1 = new UnityContainer()
                .AddNewExtension<Interception>()
                .RegisterType<IOutput, UnityAOP.OutputImplement1>();
            container1.Configure<Interception>()
                .SetDefaultInterceptorFor<IOutput>(new InterfaceInterceptor());
            var op1 = container1.Resolve<IOutput>();
            op1.Output("1dfsdfssdfsdfsdfdf0");
            Console.ReadLine();
        }
    }
}