为什么WF4约束不适用于Activity和CodeActivity父类型
问题描述:
我想将约束设置为活动以防止将其添加到某些其他活动。 我认为GetParentChain存在问题。我做了一切像在MSDN样本:为什么WF4约束不适用于Activity和CodeActivity父类型
我有三个活动: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);
}
SqlActivity:
public sealed class SqlActivity : BaseActivity
{
public Activity Activity { get; set; }
}
public abstract class BaseActivity : Activity
{
protected ActivityConstraintsProvider ActivityConstraintsProvider;
}
MyActivity:
public sealed class MyActivity : BaseActivity
{
public MyActivity()
{
ActivityConstraintsProvider = new ActivityConstraintsProvider();
ActivityConstraintsProvider.AddNotAcceptedParentActivity(typeof(SqlActivity));
ActivityConstraintsProvider.AddNotAcceptedParentActivity(typeof(SqlNativeActivity));
base.Constraints.Add(ActivityConstraintsProvider.CheckParent());
}
}
我写了ActivityConstraintsProvider,我在其中定义了List,但没有接受父类型。 ActivityConstraintsProvider:
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;
}
}
最后主营:
class Program
{
static void Main()
{
ValidationResults results;
Activity wf3 = new SqlActivity
{
Activity = new Sequence()
{
Activities =
{
new MyActivity
{
}
}
}
};
results = ActivityValidationServices.Validate(wf3);
Console.WriteLine("WF3 (SqlActivity):");
PrintResults(results);
//----------------------------------------------------------------
Activity wf4 = new SqlNativeActivity
{
Activity = new Sequence()
{
Activities =
{
new MyActivity
{
}
}
}
};
results = ActivityValidationServices.Validate(wf4);
Console.WriteLine("WF4 (SqlNativeActivity):");
PrintResults(results);
//----------------------------------------------------------------
}
static void PrintResults(ValidationResults results)
{
Console.WriteLine();
if (results.Errors.Count == 0 && results.Warnings.Count == 0)
{
Console.WriteLine(" No warnings or errors");
}
else
{
foreach (ValidationError error in results.Errors)
{
Console.WriteLine(" Error: " + error.Message);
}
foreach (ValidationError warning in results.Warnings)
{
Console.WriteLine(" Warning: " + warning.Message);
}
}
Console.WriteLine();
}
}
而问题是,如果我的SQL活动是从System.Activities.NativeActivity inherites(SqlNativeActivity)约束工作得很好,但如果我定义了约束条件,父项是来自System.Activities.Activity或System.Activities.CodeActivity约束验证的活动继承根本不起作用。 有人可以帮我解决我的问题吗? 预先感谢您:)
答
如果你创建一个自定义活动(从System.Activities.CodeActivity继承),您的验证应该在CacheMetaData完成:
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
//Validate here
base.CacheMetadata(metadata);
}