.net 4.0 为什么WF4约束不适用于活动和CodeActivity父项';s型

.net 4.0 为什么WF4约束不适用于活动和CodeActivity父项';s型,.net-4.0,workflow-foundation-4,constraints,workflow-activity,.net 4.0,Workflow Foundation 4,Constraints,Workflow Activity,我想将约束设置为“活动”,以防止将其添加到其他一些活动中。 我觉得GetParentChain有问题。我做了msdn示例中的所有事情: 我有三个活动:MyActivity、SqlNativeActivity和SqlActivity。这些类看起来像: SqlNativeActivity: public sealed class SqlNativeActivity : BaseNativeActivity { public Activity Activity { get; set; }

我想将约束设置为“活动”,以防止将其添加到其他一些活动中。 我觉得GetParentChain有问题。我做了msdn示例中的所有事情:

我有三个活动:MyActivity、SqlNativeActivity和SqlActivity。这些类看起来像:

SqlNativeActivity:

public sealed class SqlNativeActivity : BaseNativeActivity
{
    public Activity Activity { get; set; }

    protected override void Execute(NativeActivityContext context)
    {
    }
}

public abstract class BaseNativeActivity : NativeActivity
{
    protected ActivityConstraintsProvider ActivityConstraintsProvider;

    protected abstract override void Execute(NativeActivityContext context);
}
public sealed class SqlActivity : BaseActivity
{
    public Activity Activity { get; set; }
}  

public abstract class BaseActivity : Activity
{
    protected ActivityConstraintsProvider ActivityConstraintsProvider;
}
public sealed class MyActivity : BaseActivity
{
    public MyActivity()
    {
        ActivityConstraintsProvider = new ActivityConstraintsProvider();
        ActivityConstraintsProvider.AddNotAcceptedParentActivity(typeof(SqlActivity));
        ActivityConstraintsProvider.AddNotAcceptedParentActivity(typeof(SqlNativeActivity));
        base.Constraints.Add(ActivityConstraintsProvider.CheckParent());
    }
} 
public class ActivityConstraintsProvider
{
    private List<Type> _notAcceptedParentActivity;

    public void AddNotAcceptedParentActivity(Type type)
    {
        if (_notAcceptedParentActivity == null)
            _notAcceptedParentActivity = new List<Type>();

        _notAcceptedParentActivity.Add(type);
    }

    public Constraint CheckParent()
    {
        var element = new DelegateInArgument<Activity>();
        var context = new DelegateInArgument<ValidationContext>();
        var result = new Variable<bool>();
        var parent = new DelegateInArgument<Activity>();

        var con = new Constraint<Activity>
        {
            Body = new ActivityAction<Activity, ValidationContext>
            {
                Argument1 = element,
                Argument2 = context,
                Handler = new Sequence
                {
                    Variables =
                    {
                        result 
                    },
                    Activities =
                    {
                        new ForEach<Activity>
                        {                                
                            Values = new GetParentChain
                            {
                                ValidationContext = context                                    
                            },
                            Body = new ActivityAction<Activity>
                            {   
                                Argument = parent, 
                                Handler = new If()
                                {                                          
                                    Condition = new InArgument<bool>((env) => _notAcceptedParentActivity.Contains(parent.Get(env).GetType())),                                        
                                    Then = new Assign<bool>
                                    {
                                        Value = true,
                                        To = result
                                    },
                                }
                            }
                        },
                        new AssertValidation
                        {
                            Assertion = new InArgument<bool> { Expression = new Not<bool, bool> { Operand = result } },
                            Message = new InArgument<string> ("Decide can't be in Sql"),                                                                
                        }
                    }
                }
            }
        };

        return con;
    }
}
SqlActivity:

public sealed class SqlNativeActivity : BaseNativeActivity
{
    public Activity Activity { get; set; }

    protected override void Execute(NativeActivityContext context)
    {
    }
}

public abstract class BaseNativeActivity : NativeActivity
{
    protected ActivityConstraintsProvider ActivityConstraintsProvider;

    protected abstract override void Execute(NativeActivityContext context);
}
public sealed class SqlActivity : BaseActivity
{
    public Activity Activity { get; set; }
}  

public abstract class BaseActivity : Activity
{
    protected ActivityConstraintsProvider ActivityConstraintsProvider;
}
public sealed class MyActivity : BaseActivity
{
    public MyActivity()
    {
        ActivityConstraintsProvider = new ActivityConstraintsProvider();
        ActivityConstraintsProvider.AddNotAcceptedParentActivity(typeof(SqlActivity));
        ActivityConstraintsProvider.AddNotAcceptedParentActivity(typeof(SqlNativeActivity));
        base.Constraints.Add(ActivityConstraintsProvider.CheckParent());
    }
} 
public class ActivityConstraintsProvider
{
    private List<Type> _notAcceptedParentActivity;

    public void AddNotAcceptedParentActivity(Type type)
    {
        if (_notAcceptedParentActivity == null)
            _notAcceptedParentActivity = new List<Type>();

        _notAcceptedParentActivity.Add(type);
    }

    public Constraint CheckParent()
    {
        var element = new DelegateInArgument<Activity>();
        var context = new DelegateInArgument<ValidationContext>();
        var result = new Variable<bool>();
        var parent = new DelegateInArgument<Activity>();

        var con = new Constraint<Activity>
        {
            Body = new ActivityAction<Activity, ValidationContext>
            {
                Argument1 = element,
                Argument2 = context,
                Handler = new Sequence
                {
                    Variables =
                    {
                        result 
                    },
                    Activities =
                    {
                        new ForEach<Activity>
                        {                                
                            Values = new GetParentChain
                            {
                                ValidationContext = context                                    
                            },
                            Body = new ActivityAction<Activity>
                            {   
                                Argument = parent, 
                                Handler = new If()
                                {                                          
                                    Condition = new InArgument<bool>((env) => _notAcceptedParentActivity.Contains(parent.Get(env).GetType())),                                        
                                    Then = new Assign<bool>
                                    {
                                        Value = true,
                                        To = result
                                    },
                                }
                            }
                        },
                        new AssertValidation
                        {
                            Assertion = new InArgument<bool> { Expression = new Not<bool, bool> { Operand = result } },
                            Message = new InArgument<string> ("Decide can't be in Sql"),                                                                
                        }
                    }
                }
            }
        };

        return con;
    }
}
MyActivity:

public sealed class SqlNativeActivity : BaseNativeActivity
{
    public Activity Activity { get; set; }

    protected override void Execute(NativeActivityContext context)
    {
    }
}

public abstract class BaseNativeActivity : NativeActivity
{
    protected ActivityConstraintsProvider ActivityConstraintsProvider;

    protected abstract override void Execute(NativeActivityContext context);
}
public sealed class SqlActivity : BaseActivity
{
    public Activity Activity { get; set; }
}  

public abstract class BaseActivity : Activity
{
    protected ActivityConstraintsProvider ActivityConstraintsProvider;
}
public sealed class MyActivity : BaseActivity
{
    public MyActivity()
    {
        ActivityConstraintsProvider = new ActivityConstraintsProvider();
        ActivityConstraintsProvider.AddNotAcceptedParentActivity(typeof(SqlActivity));
        ActivityConstraintsProvider.AddNotAcceptedParentActivity(typeof(SqlNativeActivity));
        base.Constraints.Add(ActivityConstraintsProvider.CheckParent());
    }
} 
public class ActivityConstraintsProvider
{
    private List<Type> _notAcceptedParentActivity;

    public void AddNotAcceptedParentActivity(Type type)
    {
        if (_notAcceptedParentActivity == null)
            _notAcceptedParentActivity = new List<Type>();

        _notAcceptedParentActivity.Add(type);
    }

    public Constraint CheckParent()
    {
        var element = new DelegateInArgument<Activity>();
        var context = new DelegateInArgument<ValidationContext>();
        var result = new Variable<bool>();
        var parent = new DelegateInArgument<Activity>();

        var con = new Constraint<Activity>
        {
            Body = new ActivityAction<Activity, ValidationContext>
            {
                Argument1 = element,
                Argument2 = context,
                Handler = new Sequence
                {
                    Variables =
                    {
                        result 
                    },
                    Activities =
                    {
                        new ForEach<Activity>
                        {                                
                            Values = new GetParentChain
                            {
                                ValidationContext = context                                    
                            },
                            Body = new ActivityAction<Activity>
                            {   
                                Argument = parent, 
                                Handler = new If()
                                {                                          
                                    Condition = new InArgument<bool>((env) => _notAcceptedParentActivity.Contains(parent.Get(env).GetType())),                                        
                                    Then = new Assign<bool>
                                    {
                                        Value = true,
                                        To = result
                                    },
                                }
                            }
                        },
                        new AssertValidation
                        {
                            Assertion = new InArgument<bool> { Expression = new Not<bool, bool> { Operand = result } },
                            Message = new InArgument<string> ("Decide can't be in Sql"),                                                                
                        }
                    }
                }
            }
        };

        return con;
    }
}
我还编写了ActivityConstraintsProvider,在其中我用不可接受的父类型定义了列表。 ActivityConstraintsProvider:

public sealed class SqlNativeActivity : BaseNativeActivity
{
    public Activity Activity { get; set; }

    protected override void Execute(NativeActivityContext context)
    {
    }
}

public abstract class BaseNativeActivity : NativeActivity
{
    protected ActivityConstraintsProvider ActivityConstraintsProvider;

    protected abstract override void Execute(NativeActivityContext context);
}
public sealed class SqlActivity : BaseActivity
{
    public Activity Activity { get; set; }
}  

public abstract class BaseActivity : Activity
{
    protected ActivityConstraintsProvider ActivityConstraintsProvider;
}
public sealed class MyActivity : BaseActivity
{
    public MyActivity()
    {
        ActivityConstraintsProvider = new ActivityConstraintsProvider();
        ActivityConstraintsProvider.AddNotAcceptedParentActivity(typeof(SqlActivity));
        ActivityConstraintsProvider.AddNotAcceptedParentActivity(typeof(SqlNativeActivity));
        base.Constraints.Add(ActivityConstraintsProvider.CheckParent());
    }
} 
public class ActivityConstraintsProvider
{
    private List<Type> _notAcceptedParentActivity;

    public void AddNotAcceptedParentActivity(Type type)
    {
        if (_notAcceptedParentActivity == null)
            _notAcceptedParentActivity = new List<Type>();

        _notAcceptedParentActivity.Add(type);
    }

    public Constraint CheckParent()
    {
        var element = new DelegateInArgument<Activity>();
        var context = new DelegateInArgument<ValidationContext>();
        var result = new Variable<bool>();
        var parent = new DelegateInArgument<Activity>();

        var con = new Constraint<Activity>
        {
            Body = new ActivityAction<Activity, ValidationContext>
            {
                Argument1 = element,
                Argument2 = context,
                Handler = new Sequence
                {
                    Variables =
                    {
                        result 
                    },
                    Activities =
                    {
                        new ForEach<Activity>
                        {                                
                            Values = new GetParentChain
                            {
                                ValidationContext = context                                    
                            },
                            Body = new ActivityAction<Activity>
                            {   
                                Argument = parent, 
                                Handler = new If()
                                {                                          
                                    Condition = new InArgument<bool>((env) => _notAcceptedParentActivity.Contains(parent.Get(env).GetType())),                                        
                                    Then = new Assign<bool>
                                    {
                                        Value = true,
                                        To = result
                                    },
                                }
                            }
                        },
                        new AssertValidation
                        {
                            Assertion = new InArgument<bool> { Expression = new Not<bool, bool> { Operand = result } },
                            Message = new InArgument<string> ("Decide can't be in Sql"),                                                                
                        }
                    }
                }
            }
        };

        return con;
    }
}
问题是,如果我的sql活动是从System.Activities.NativeActivity(SqlNativeActivity)继承的,那么约束工作得很好,但是如果我定义了约束并且父项是从System.Activities.activity或System.Activities.CodeActivity继承的活动,那么活动约束验证根本不起作用。 有人能帮我解决问题吗?
提前感谢:)

如果创建自定义活动(从System.Activities.CodeActivity继承),则应在CacheMatadata处进行验证:

    protected override void CacheMetadata(CodeActivityMetadata metadata)
    {
        //Validate here

        base.CacheMetadata(metadata);
    }