workflow-foundation-4 - 如何使用 System.Activities.Validation.GetParentChain?

标签 workflow-foundation-4

我有一个外部事件,它有一个 body ,你可以将其他事件拖到它上面。然后我有几个内部事件,它们必须是外部事件的后代。我想添加设计时验证以确保内部放置在外部中。

我听说我“can use System.Activities.Validation.GetParentChain to enumerate all of the parents of an activity during the validation step”。但即使看完the documentation for the class ,我不知道如何使用它。

我认为我在内部类的 CacheMetadata 中使用它。我想使用 foreach(varances in parentChain) { ... },并确保至少有一个祖先是 Outer 类型的。不知道该怎么做。

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

最佳答案

正如您可以通过 documentation 看到的GetParentChain是正规的 CodeActivity .您可以与 Activity.Constraints 一起使用.

约束在设计时执行,就像 CacheMetadata() ,但您可以访问上下文(当然是此时的 ValidationContext)。否则,您将无法了解上层事件。

让我们看看我是否理解你的情况,以及这个例子是否涵盖了它。基本上它循环通过 IEnumerable<Activity>返回者 GetParentChain并检查是否有任何 Inner 的 parent 是 Outer。这样可以确保 Inner 始终位于 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"
                        }
                    }
                }
            }
        };
    }
}

如果你想允许多个外层,你必须一个一个地检查它们,用循环遍历数组(使用 ForEach)或多个嵌套的 Ifs。

例如,有多个 if,并继续上面的代码:
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;
    }
}

这样你就可以通过代码来做到这一点。

好吧,我想你明白了!

关于workflow-foundation-4 - 如何使用 System.Activities.Validation.GetParentChain?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8016606/

相关文章:

build-automation - 无法在自定义构建过程模板中删除 TFS2010 的自定义工作流事件

wcf - 工作流服务中的HandleError vs. ProvideFault不一致,如何处理?

async-await - AsyncTaskCodeActivity 和等待后丢失的上下文

.net - XAML 事件的分类属性

wcf - WF 4 中与工作流 InstanceId 的相关性

workflow-foundation-4 - Windows工作流程4:WorkflowApplication取消,终止和中止之间的区别

dynamics-crm - CRM 2011 工作流 : Finding the previous values

c#-4.0 - Workflow Foundation - Literal 仅支持值类型和不可变类型 System.String

.net - 如何使用 InvokeMethod 事件将字符串添加到使用 Workflow Foundation 4 的通用列表

asp.net-mvc - Windows Workflow Foundation 4 和 ASP.NET MVC