Prosty Sequential Workflow

Dzisiaj spróbujemy stworzyć pierwszy workflow. Co prawda, nic praktycznego nie będzie wykonywał, ale pokaże kilka mechanizmów, które można wykorzystać w workflow. Zasada działania przykładowego workflow wzorowana jest na przykładzie z MSDN:

  1. Jako parametr wejściowy podajemy liczbę całkowitą,
  2. Workflow sprawdza wartość liczby. Jeśli jest mniejsza niż 2000, kończy działanie wysyłając e-mail. W przeciwnym razie, wymagana jest akceptacja wprowadzonej wartości. Użytkownik musi po prostu wywołać pewnie zdarzenie – wtedy workflow będzie kontynuował pracę.

Do dzieła wiec:

1. Zaczynamy od stworzenia odpowiedniego projektu. Wybieramy “Sequential Workflow Library”.

 

image

 

Po utworzeniu mamy do dyspozycji pusty workflow:

image

Ponadto oprócz wizualnego wsparcia, możemy wszystkie operacje wykonywać bezpośrednio w kodzie. Wygląda to tak jak w przypadku aplikacji WindowsForms – użytkownik może dodawać kontrolki zarówno z poziomu IDE jak i czystego kodu.

2. Przed opracowaniem workflow’a, zdefiniujmy niezbędne parametry wejściowe. W naszym przypadku jest to po prostu liczba całkowita. Wszelkie parametry wejściowe i wyjściowe w WWF definiujemy jako właściwości:

public sealed partial class Workflow1 : SequentialWorkflowActivity
{
   public Workflow1()
   {
       InitializeComponent();
   }
   private int m_Number = 0;
   public int Number
   {
       set { m_Number = value; }
   }
}

Użytkownik będzie mógł w aplikacji hostującej przekazać wartości za pomocą słownika (Dictionary<string,object>). Dokładnie jak to się robi przedstawię w następnym poście kiedy będzie mowa o kliencie workflow.

3. Ponadto potrzebujemy pewnego interfejsu, który będzie stanowił medium komunikacyjne między klientem a workflow. W naszym przypadku będzie on zawierał m.in. metodę odpowiedzialną za wysłanie e-mail’a oraz zdarzenie, które poiwnno przychodzić po zatwierdzeniu przez użytkownika podanej liczby. Co prawda wysłanie e-mail’a może odbywać się bezpośrednio w workflow, jednak uważam, że workflow powinien zawierać wyłącznie logikę a nie szczegóły techniczne.

[ExternalDataExchange]
public interface IService
{
   void NotifyUser(string message);
   void Approve();
   event EventHandler<ExternalDataEventArgs> OnApproved;
}

Interfejs musi być opatrzony również atrybutem ExternalDataExchange. Workflow wywołuje NotifyUser kiedy chce powiadomić użytkownika (np. za pomocą e-mail’a). Jeśli liczba wymaga akceptacji, worklflow wywołuje metodę Approve. Wtedy klient może je zaakceptować poprzez wysłanie zdarzenia OnApproved.

4. Przyszedł czas na implementacje samego workfow’a. Na początku musimy sprawdzić wartość Number, zatem wrzucamy aktywność IfElse:

image Klikamy na pierwszą gałąź (ifElseBranchActivity1) i w oknie properties rozwijamy węzeł Condition (który musi być ustawiony na Declarative Rule Condition). Wybieramy ConditionName. Powinno pojawić się następujące okienko:

image

Tworzymy nowy warunek, wpisując w pole edycyjne:

this.m_Number<2000

Podobne operacje wykonujemy dla drugiej gałęzi, z tym, że jako warunek podajemy m_Number>=2000. Po zakończeniu powinniśmy mieć  utworzone dwa warunki (np. Condition1, Condition2).

5. Gdy liczba jest mniejsza niż 2000, chcemy powiadomić użytkownika za pomocą metody NotifyUser. W tym celu do lewej gałęzi wrzucamy aktywność CallExternalActivity:

image

Ustawiamy właściwość InterfaceType na IService, MethodName na NotifyUser. Z kolei parametr wejściowy message ustawiamy na jakiś komunikat np. “Liczba mniejsza niż 2000”.

image

6. W drugiej gałęzi wywołujemy metodę Approve a następnie oczekujemy na zdarzenie zwrotne OnApproved. Wrzucamy zatem aktywności CallExternalMethod oraz HandleExternalMethod:

image

CallExternalMethod wypełniamy w analogiczny  sposób jak w poprzednim kroku (InterfaceType – IService, MethodName– Approve).

HandleExternalMethod blokuje wykonywanie workflow aż do momentu przyjścia konkretnego zdarzenia. W naszym przypadku chcemy czekać aż przyjdzie OnApproved więc ustawiamy EventName na OnApproved oraz oczywiście InterfaceType na IService.

image

7. Na zakończenie przy wejściu z IF można umieścić jeszcze aktywność CallExternalMethod, która wywołuje metodę NotifyUser przekazując jakiś komunikat.

image

Po kompilacji zostanie utworzona biblioteka dll. W kolejnym poście pokaże jak wykorzystać WWF w aplikacji klienckiej (np. w WPF).

Kompletny kod źródłowy.

One thought on “Prosty Sequential Workflow”

Leave a Reply

Your email address will not be published.