Написание рабочего процесса Workflow Foundation с использованием C # - PullRequest
0 голосов
/ 27 августа 2010

Я пытаюсь написать некоторые действия с C # вместо дизайнера и XAML.VS2010 был глючным и очень медленным для этого, а также имеет очень плохую поддержку компиляции (для имен переменных, свойств и т. Д.).

Поэтому я пытаюсь создавать действия, наследуя их непосредственно от класса Activity, но я сталкиваюсь с ошибкой.

Вот мой код:

public class TestActivity : Activity
{
    public InArgument<string> Username { get; set; }
    public InArgument<string> Password { get; set; }
    public OutArgument<bool> ValidCredential { get; set; }
    public OutArgument<ProvisioningRole> Role { get; set; }
    public OutArgument<Guid> Guid { get; set; }

    protected override Func<Activity> Implementation
    {
        get
        {
            return () =>
                {
                    return new Sequence()
                    {
                        Activities =
                        {
                            new AuthenticateUserActivity()
                            {
                                Username = this.Username,
                                Password = this.Password,
                                Guid = this.Guid,
                                Result = this.ValidCredential
                            },
                            new If()
                            {
                                Condition = this.ValidCredential,
                                Then = new GetUserRoleActivity()
                                {
                                    Username = this.Username,
                                    Password = this.Password,
                                    Result = this.Role
                                }
                            },
                        }
                    };
                };
        }
        set { base.Implementation = value; }
    }
}

Проблема с условием If ().Предполагается, что это InArgument, но this.ValidCredential является OutArgument.Я пытался создать переменную, присвоить ей значение ValidCredential.Я также попытался поместить результат AuthenticateUserActivity в переменную, а затем присвоить его ValidCredential, но я получаю сообщение об ошибке, в котором необходимо указать свойство To в Assign.

Я искал подходящие учебники,но все, что я нашел, была статья MSDN, в которой была быстрая и грязная реализация кода, и в ней использовались литералы вместо переданных аргументов, поэтому никакой помощи оттуда не было.

Ответы [ 3 ]

5 голосов
/ 01 сентября 2010

Я узнал, как это сделать. Вам просто нужно создать новый InArgument из оригинального. Есть конструктор, который принимает выражение для него.

Username = new InArgument<bool>((ActivityContext c) => this.ValidCredential.Get(c))

Так что я изменил всю свою деятельность на

return new CompensableActivity()
{
    Body = new Sequence()
    {
        Activities =
            {
                new AuthenticateUserActivity()
                {
                    Username = this.Username.In(),
                    Password = this.Password.In(),
                    Guid = this.Guid.Out(),
                    Result = this.ValidCredential.Out()
                },
                new If(this.ValidCredential.In())
                {
                    Then = new GetUserRoleActivity()
                    {
                        Username = this.Username.In(),
                        Password = this.Password.In(),
                        Result = this.Role.Out()
                    },
                    Else = new Assign<ProvisioningRole>()
                    {
                        To = this.Role.Out(),
                        Value = ProvisioningRole.User
                    }
                }
            }
    },
};

In и Out - методы расширения, я написал:

public static class WorkflowExtensions
{
    #region In
    public static InArgument<T> In<T>(this InArgument<T> self)
    {
        return new InArgument<T>(context => self.Get(context));
    }

    public static InArgument<T> In<T>(this OutArgument<T> self)
    {
        return new InArgument<T>(context => self.Get(context));
    }
    #endregion

    #region Out
    public static OutArgument<T> Out<T>(this InArgument<T> self)
    {
        return new OutArgument<T>(context => self.Get(context));
    }

    public static OutArgument<T> Out<T>(this OutArgument<T> self)
    {
        return new OutArgument<T>(context => self.Get(context));
    }
    #endregion
}

А теперь все хорошо!

1 голос
/ 31 августа 2010

Вы должны быть в состоянии заставить это работать. Основной подход должен состоять в том, чтобы использовать переменную для хранения данных, использовать OutArgument для извлечения данных из действий в переменную и InArguments для передачи данных из переменной в действие.

Также обратите внимание, что выражения для привязки InArguments к переменным являются выражениями VisualBasicValue. Так что-то вроде:

Условие = новое VisualBasicValue ("System.DateTime.Now.Hour <12") </p>

Этот пост в блоге не об использовании аргументов и переменных, а показывает пару примеров.

0 голосов
/ 17 марта 2011

Собираюсь бесстыдно подключить свою собственную библиотеку, которую я в итоге сделал для этого: http://code.google.com/p/system-transactions/

Позволяет базовую компенсацию кода без излишних хлопот WF.Кроме того, правильно компилируется и легко отлаживается.

...