我如何使用System.Activities.Validation.GetParentChain?(How do I use System.Activities.Validation.GetParen

编程入门 行业动态 更新时间:2024-10-28 10:30:01
如何使用System.Activities.Validation.GetParentChain?(How do I use System.Activities.Validation.GetParentChain?)

我有一个外部活动,其中有一个Body,您可以拖动其他活动。 然后,我有几个内部活动,必须是外部活动的后代。 我想添加设计时验证以确保内部放置在外部。

我听说我“ 可以使用System.Activities.Validation.GetParentChain在验证步骤中枚举活动的所有父项 ”。 但即使在阅读了该课程的文档后,我也不知道如何使用它。

我想我会在Inner类的CacheMetadata中使用它。 我想使用foreach(parentChain中的var ancestor){...},并确保至少有一个祖先是Outer类型。 不知道该怎么做。

任何人都可以解释如何在设计时验证内部活动是外部活动的后代吗?

I've got an Outer activity which has a Body onto which you drag other activities. I then have several Inner activities, which MUST be a descendent of an Outer activity. I'd like to add design-time validation to ensure the Inner is placed within an Outer.

I've heard that I "can use System.Activities.Validation.GetParentChain to enumerate all of the parents of an activity during the validation step". But even after reading the documentation for the class, I have no idea how to use it.

I would think I use it inside CacheMetadata in my Inner class. I'd like to use have a foreach(var ancestor in parentChain) { ... }, and make sure at least one ancestor is of type Outer. Not sure how to do that.

Can anyone explain how to validate at design time that an Inner activity is a descendant of an Outer activity?

最满意答案

正如您可以通过文档看到的, GetParentChain是一个常规的CodeActivity 。 您可以将它与Activity.Constraints结合使用。

约束在设计时执行,就像CacheMetadata() ,但您可以访问上下文(当然,此时为ValidationContext )。 否则你将无法知道上层活动。

让我们看看我是否理解你的情况,如果这个例子涵盖了它。 基本上,它循环通过GetParentChain返回的IEnumerable<Activity> ,并检查Inner的父母是否为外部 。 这样就可以确保Inner始终位于外部

public sealed class Inner : CodeActivity { public Inner() { Constraints.Add(MustBeInsideOuterActivityConstraint()); } protected override void Execute(CodeActivityContext context) { // Execution logic here } private Constraint<Inner> MustBeInsideOuterActivityConstraint() { var activityBeingValidated = new DelegateInArgument<Inner>(); var validationContext = new DelegateInArgument<ValidationContext>(); var parent = new DelegateInArgument<Activity>(); var parentIsOuter = new Variable<bool>(); return new Constraint<Inner> { Body = new ActivityAction<Inner, ValidationContext> { Argument1 = activityBeingValidated, Argument2 = validationContext, Handler = new Sequence { Variables = { parentIsOuter }, Activities = { new ForEach<Activity> { Values = new GetParentChain { ValidationContext = validationContext }, Body = new ActivityAction<Activity> { Argument = parent, Handler = new If { Condition = new InArgument<bool>(env => object.Equals(parent.Get(env).GetType(), typeof(Outer))), Then = new Assign<bool> { To = parentIsOuter, Value = true } } } }, new AssertValidation { Assertion = parentIsOuter, Message = "Inner must be inside Outer" } } } } }; } }

如果你想允许多个Outers,你必须逐个检查它们,通过一个数组循环(使用ForEach)或多个嵌套的Ifs。

例如,使用多个ifs,并继续上面的代码:

Handler = new If { Condition = new InArgument<bool>(env => object.Equals(parent.Get(env).GetType(), typeof(OuterONE))), Then = new Assign<bool> { To = parentIsOuter, Value = true } Else = new If { Condition = new InArgument<bool>(env => object.Equals(parent.Get(env).GetType(), typeof(OuterTWO))), Then = new Assign<bool> { To = parentIsOuter, Value = true }, Else = new If { // and continue with other Outers } } }

简而言之,使用活动的If-then-else语句。

其他选项,我从来没有测试,但它似乎相当合理,因为你可以使用约束内的活动,将所有这些逻辑抛出一个活动,其唯一的工作是检查是否类型如果外部:

public sealed CheckIfTypeIsOuter<T> : CodeActivity<bool> { protected override bool Execute() { if (typeof(T) == typeof(Outer1)) return true; if (typeof(T) == typeof(Outer2)) return true; if (typeof(T) == typeof(Outer3)) return true; if (typeof(T) == typeof(Outer4)) return true; return false; } }

这样你就可以通过代码完成。

好吧,我想你明白了!

As you can see through the documentation GetParentChain is a regular CodeActivity. You can use it in conjunction with Activity.Constraints.

Constraints are executed at design time, just like CacheMetadata(), but you have the ability to access the context (the ValidationContext at this point, of course). Otherwise you wouldn't be able to known the upper level activities.

Lets see if I understood your case right and if this example covers it. Basically it loops through IEnumerable<Activity> returned by GetParentChain and checks if any of Inner's parents is an Outer. This way it ensures that Inner is always inside an Outer.

public sealed class Inner : CodeActivity { public Inner() { Constraints.Add(MustBeInsideOuterActivityConstraint()); } protected override void Execute(CodeActivityContext context) { // Execution logic here } private Constraint<Inner> MustBeInsideOuterActivityConstraint() { var activityBeingValidated = new DelegateInArgument<Inner>(); var validationContext = new DelegateInArgument<ValidationContext>(); var parent = new DelegateInArgument<Activity>(); var parentIsOuter = new Variable<bool>(); return new Constraint<Inner> { Body = new ActivityAction<Inner, ValidationContext> { Argument1 = activityBeingValidated, Argument2 = validationContext, Handler = new Sequence { Variables = { parentIsOuter }, Activities = { new ForEach<Activity> { Values = new GetParentChain { ValidationContext = validationContext }, Body = new ActivityAction<Activity> { Argument = parent, Handler = new If { Condition = new InArgument<bool>(env => object.Equals(parent.Get(env).GetType(), typeof(Outer))), Then = new Assign<bool> { To = parentIsOuter, Value = true } } } }, new AssertValidation { Assertion = parentIsOuter, Message = "Inner must be inside Outer" } } } } }; } }

If you want to allow multiple Outers, you have to check them, one by one, wither with a loop through an array (using ForEach) or multiple nested Ifs.

For example, with multiple ifs, and continuing with the code above:

Handler = new If { Condition = new InArgument<bool>(env => object.Equals(parent.Get(env).GetType(), typeof(OuterONE))), Then = new Assign<bool> { To = parentIsOuter, Value = true } Else = new If { Condition = new InArgument<bool>(env => object.Equals(parent.Get(env).GetType(), typeof(OuterTWO))), Then = new Assign<bool> { To = parentIsOuter, Value = true }, Else = new If { // and continue with other Outers } } }

In short, an If-then-else statement using activities.

Other option that I've never tested but that it seems pretty plausible, and because you can use activities inside constraints, is throw all this logic inside an activity which its only job is to check if type if an Outer:

public sealed CheckIfTypeIsOuter<T> : CodeActivity<bool> { protected override bool Execute() { if (typeof(T) == typeof(Outer1)) return true; if (typeof(T) == typeof(Outer2)) return true; if (typeof(T) == typeof(Outer3)) return true; if (typeof(T) == typeof(Outer4)) return true; return false; } }

This way you can do it through code.

Well, I guess you get the idea!

更多推荐

本文发布于:2023-08-07 12:11:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1464172.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:如何使用   System   Activities   Validation   GetParentChain

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!