Почему ограничения WF4 не работают с типами родителя Activity и CodeActivity - PullRequest
0 голосов
/ 14 марта 2012

Я хочу установить ограничение на действие, чтобы не добавлять его в некоторые другие действия. У меня проблема с 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);
}

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 (SqlNativeActivity), ограничения работают очень хорошо, но если я определю ограничения, а parent - активность, наследуется от System.Activities.Activity или System.Activities. Проверка ограничений CodeActivity вообще не работает. Кто-нибудь может помочь мне с моей проблемой? Заранее спасибо:)

1 Ответ

0 голосов
/ 29 марта 2012

если вы создаете пользовательское действие (наследуемое от System.Activities.CodeActivity), ваша проверка должна быть выполнена в CacheMetaData:

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

        base.CacheMetadata(metadata);
    }
...