1 //----------------------------------------------------------------------------- 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //----------------------------------------------------------------------------- 4 5 namespace System.Activities.Validation 6 { 7 using System; 8 using System.Collections.Generic; 9 using System.Diagnostics.CodeAnalysis; 10 using System.Runtime; 11 using System.Windows.Markup; 12 using System.Collections.ObjectModel; 13 14 public abstract class Constraint : NativeActivity 15 { 16 public const string ValidationErrorListPropertyName = "System.Activities.Validation.Constraint.ValidationErrorList"; 17 18 internal const string ToValidateArgumentName = "ToValidate"; 19 internal const string ValidationErrorListArgumentName = "ViolationList"; 20 internal const string ToValidateContextArgumentName = "ToValidateContext"; 21 22 RuntimeArgument toValidate; 23 RuntimeArgument violationList; 24 RuntimeArgument toValidateContext; 25 Constraint()26 internal Constraint() 27 { 28 this.toValidate = new RuntimeArgument(ToValidateArgumentName, typeof(object), ArgumentDirection.In); 29 this.toValidateContext = new RuntimeArgument(ToValidateContextArgumentName, typeof(ValidationContext), ArgumentDirection.In); 30 this.violationList = new RuntimeArgument(ValidationErrorListArgumentName, typeof(IList<ValidationError>), ArgumentDirection.Out); 31 } 32 AddValidationError(NativeActivityContext context, ValidationError error)33 public static void AddValidationError(NativeActivityContext context, ValidationError error) 34 { 35 List<ValidationError> validationErrorList = context.Properties.Find(ValidationErrorListPropertyName) as List<ValidationError>; 36 37 if (validationErrorList == null) 38 { 39 throw FxTrace.Exception.AsError(new InvalidOperationException(SR.AddValidationErrorMustBeCalledFromConstraint(typeof(Constraint).Name))); 40 } 41 42 validationErrorList.Add(error); 43 } 44 CacheMetadata(NativeActivityMetadata metadata)45 protected override void CacheMetadata(NativeActivityMetadata metadata) 46 { 47 metadata.SetArgumentsCollection( 48 new Collection<RuntimeArgument> 49 { 50 this.toValidate, 51 this.violationList, 52 this.toValidateContext 53 }); 54 } 55 Execute(NativeActivityContext context)56 protected override void Execute(NativeActivityContext context) 57 { 58 object objectToValidate = this.toValidate.Get<object>(context); 59 ValidationContext objectToValidateContext = this.toValidateContext.Get<ValidationContext>(context); 60 61 if (objectToValidate == null) 62 { 63 throw FxTrace.Exception.AsError(new InvalidOperationException(SR.CannotValidateNullObject(typeof(Constraint).Name, this.DisplayName))); 64 } 65 66 if (objectToValidateContext == null) 67 { 68 throw FxTrace.Exception.AsError(new InvalidOperationException(SR.ValidationContextCannotBeNull(typeof(Constraint).Name, this.DisplayName))); 69 } 70 71 List<ValidationError> validationErrorList = new List<ValidationError>(1); 72 context.Properties.Add(ValidationErrorListPropertyName, validationErrorList); 73 74 this.violationList.Set(context, validationErrorList); 75 76 OnExecute(context, objectToValidate, objectToValidateContext); 77 } 78 79 [SuppressMessage(FxCop.Category.Naming, FxCop.Rule.IdentifiersShouldNotContainTypeNames, 80 Justification = "Can't replace object with Object because of casing rules")] OnExecute(NativeActivityContext context, object objectToValidate, ValidationContext objectToValidateContext)81 protected abstract void OnExecute(NativeActivityContext context, object objectToValidate, ValidationContext objectToValidateContext); 82 } 83 84 [ContentProperty("Body")] 85 public sealed class Constraint<T> : Constraint 86 { Constraint()87 public Constraint() 88 { 89 } 90 91 public ActivityAction<T, ValidationContext> Body 92 { 93 get; 94 set; 95 } CacheMetadata(NativeActivityMetadata metadata)96 protected override void CacheMetadata(NativeActivityMetadata metadata) 97 { 98 base.CacheMetadata(metadata); 99 100 if (this.Body != null) 101 { 102 metadata.SetDelegatesCollection(new Collection<ActivityDelegate> { this.Body }); 103 } 104 } 105 OnExecute(NativeActivityContext context, object objectToValidate, ValidationContext objectToValidateContext)106 protected override void OnExecute(NativeActivityContext context, object objectToValidate, ValidationContext objectToValidateContext) 107 { 108 if (this.Body != null) 109 { 110 context.ScheduleAction(this.Body, (T)objectToValidate, objectToValidateContext); 111 } 112 } 113 } 114 } 115