Lab Windows Workflow Foundation (VS2008)



Podobne dokumenty
Windows Workflow Foundation (wprowadzenie - prosty przykład Sequential Workflow):

- Narzędzie Windows Forms. - Przykładowe aplikacje. Wyższa Metody Szkoła programowania Techniczno Ekonomiczna 1 w Świdnicy

Laboratorium 10 - Web Services

Platforma.NET. Laboratorium nr 1 Podstawy języka C#

Wykład 12. Programowanie serwera MS SQL 2005 w C#

Zaawansowane aplikacje internetowe - laboratorium Web Services (część 1).

Narzędzia i aplikacje Java EE. Usługi sieciowe Paweł Czarnul pczarnul@eti.pg.gda.pl

Windows Workflow Foundation

Ćwiczenie 1. Kolejki IBM Message Queue (MQ)

Wykład 4 Delegat (delegate), właściwości indeksowane, zdarzenie (event) Zofia Kruczkiewicz

Przykładowa dostępna aplikacja w Visual Studio - krok po kroku

Aplikacje WWW - laboratorium

Programowanie obiektowe i zdarzeniowe wykład 4 Kompozycja, kolekcje, wiązanie danych

Instrukcja 10 Laboratorium 13 Testy akceptacyjne z wykorzystaniem narzędzia FitNesse

Wykład 5 Okna MDI i SDI, dziedziczenie

Projektowanie aplikacji internetowych laboratorium

Programowanie obiektowe

AXIS2 - tworzenie usługi sieciowej i klienta Axis Data Binding. dr inż. Juliusz Mikoda mgr inż. Anna Wawszczak

Programowanie obiektowe i zdarzeniowe

WYKONANIE APLIKACJI OKIENKOWEJ OBLICZAJĄCEJ SUMĘ DWÓCH LICZB W ŚRODOWISKU PROGRAMISTYCZNYM. NetBeans. Wykonał: Jacek Ventzke informatyka sem.

Prosta książka telefoniczna z wykorzystaniem zapisu do pliku

1 LINQ. Zaawansowane programowanie internetowe Instrukcja nr 1

Informatyka II. Laboratorium Aplikacja okienkowa

Wykład 4: Klasy i Metody

Zaawansowane aplikacje WWW - laboratorium

Języki i metody programowania Java Lab2 podejście obiektowe

Visual Studio instalacja

xmlns:prism= c. <ContentControl prism:regionmanager.regionname="mainregion" />

Budowa aplikacji wielowarstwowych zastosowanie szablonów. Laboratorium 2 Programowanie komponentowe Zofia Kruczkiewicz

Rozdział 4 KLASY, OBIEKTY, METODY

Utworzenie aplikacji mobilnej Po uruchomieniu Visual Studio pokazuje się ekran powitalny. Po lewej stronie odnośniki do otworzenia lub stworzenia

imei CYFROWE PRZETWARZANIE SYGNAŁÓW Laboratorium Temat: Tworzenie aplikacji w środowisku LabWindows/CVI Instytut Metrologii, Elektroniki i Informatyki

PWSG Ćwiczenia 12. Wszystkie ukończone zadania należy wysłać na adres: lub

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Metody Metody, parametry, zwracanie wartości

TEMAT : KLASY DZIEDZICZENIE

Języki i metody programowania Java Lab1 Zofia Kruczkiewicz

Programowanie obiektowe

Wybieramy File->New->Project Wybieramy aplikację MFC->MFC Application jak na rysunku poniżej:

Języki i metodyka programowania. Język C# pętle, sterowanie, wyjątki

Platformy Programowania

1. Czynności przygotowujące aplikację działającą na platformie Java SE Biblioteka5 (należy ją pobrać z załącznika z p.1)

Kurs programowania. Wykład 9. Wojciech Macyna. 28 kwiecień 2016

Programowanie Komputerów

Programowanie telefonów z Windows Phone 7, cz. 4

D:\DYDAKTYKA\ZAI_BIS\_Ćwiczenia_wzorce\04\04_poprawiony.doc 2009-lis-23, 17:44

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

ASP.NET MVC. Podstawy. Zaawansowane programowanie internetowe Instrukcja nr 3

Podstawy programowania obiektowego

Sposoby tworzenia projektu zawierającego aplet w środowisku NetBeans. Metody zabezpieczenia komputera użytkownika przed działaniem apletu.

Aplikacje internetowe i rozproszone - laboratorium

Wprowadzenie do programowania w języku Visual Basic. Podstawowe instrukcje języka

Aplikacje w środowisku Java

Instytut Sterowania i Systemów Informatycznych Uniwersytet Zielonogórski SYSTEMY SCADA

Microsoft.NET: ASP.NET MVC + Entity Framework (Code First)

Rozdział 3. Zapisywanie stanu aplikacji w ustawieniach lokalnych

Pracownia internetowa w każdej szkole (edycja Jesień 2007)

Modelowanie obiektowe - Ćw. 1.

Programowanie telefonów z Windows Phone 7, cz. 2

2. W oknie dialogowym Choose Toolbox Items w zakładce.net Framework Components naciskamy przycisk Browse...

Karty pracy. Ustawienia. W tym rozdziale została opisana konfiguracja modułu CRM Karty pracy oraz widoki i funkcje w nim dostępne.

Protokół JDBC współpraca z relacyjnymi bazami danych lab4. Dr inż. Zofia Kruczkiewicz Programowanie aplikacji internetowych

Programowanie w Javie

1. Co można powiedzieć o poniższym kodzie? public interface I { void m1() {}; static public void m2() {}; void abstract m3();

Kurs walut. Specyfikacja projektu. Marek Zając

Kurs programowania. Wykład 13. Wojciech Macyna. 14 czerwiec 2017

Tworzenie i wykorzystanie usług sieciowych

Fragmenty są wspierane od Androida 1.6

Instrukcja laboratoryjna cz.3

Instrukcja obsługi certyfikatu kwalifikowanego w programie Płatnik.

Programowanie wielowarstwowe i komponentowe

Zaawansowane aplikacje internetowe - laboratorium

Klasy i obiekty cz II

Politechnika Gdańska Katedra Optoelektroniki i Systemów Elektronicznych

Microsoft.NET: LINQ to SQL, ASP.NET AJAX

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Ćwiczenia 9 - Swing - część 1

Instytut Sterowania i Systemów Informatycznych Uniwersytet Zielonogórski SYSTEMY SCADA

Db4o obiektowa baza danych wersja.net

Obiekt klasy jest definiowany poprzez jej składniki. Składnikami są różne zmienne oraz funkcje. Składniki opisują rzeczywisty stan obiektu.

dr inż. Piotr Czapiewski Tworzenie aplikacji w języku Java Laboratorium 1

Programowanie obiektowe

Instrukcja 5 Laboratorium z Podstaw Inżynierii Oprogramowania. Warstwy integracji z bazą danych: Wzorzec DAO Technologia ORM

Instalacja systemu zarządzania treścią (CMS): Joomla

Zaawansowane aplikacje internetowe - laboratorium Architektura CORBA.

Podstawy programowania. Ćwiczenie. Pojęcia bazowe. Języki programowania. Środowisko programowania Visual Studio

Wprowadzenie do projektu QualitySpy

Programowanie komponentowe. Przykład 1 Bezpieczeństwo wg The Java EE 5 Tutorial Autor: Zofia Kruczkiewicz

Instrukcja pomocnicza do przygotowania sprawozdania Zgłoszenie zaangażowania

Programowanie w środowiskach graficznych. Wykład 3 Język C#

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Wstęp - Prosta aplikacja internetowa w technologii Java EE 5. Programowanie komponentowe 1

LINQ TO XML. Autor ćwiczenia: Marcin Wolicki

Programowanie Obiektowe GUI

Ćwiczenie 1. Modelowanie prostego procesu

etrader Pekao Podręcznik użytkownika Strumieniowanie Excel

Politechnika Poznańska Wydział Budowy Maszyn i Zarządzania

Transkrypt:

Lab Windows Workflow Foundation (VS2008) Zadanie 1- utworzenie prostej własnej czynności (custom activity). Otworzyć nowy projekt typu Workflow -> Workflow Activity Library W Properties ach zmień w polu Name nazwę Activity1 na np. WritelineActivity Wybrać z menu kontekstowego View Code Utworzymy nową własną czynność WritelineActivity wypisującą na konsolę treść przekazaną do niej w polu właściwości komunikat. Należy więc nadpisać metodę Execute: ///<summary> /// wykonuje aktywnosc - wyswietla komunikat na ekranie ///</summary> ///<param name="executioncontext"></param> ///<returns></returns> protected override ActivityExecutionStatus Execute(ActivityExecutionContext executioncontext) Console.WriteLine(komunikat); Console.WriteLine("wciśnij klawisz aby kontynuować wykonanie workflow..."); Console.ReadLine(); return ActivityExecutionStatus.Closed; /// <summary> /// get/set tresc komunikatu do wyswietlenia /// </summary> [Description("komunikat do wyswietlenia")] [Category("Parameters")] public string komunikat get return _mes; set _mes = value; private string _mes; Teraz dodamy w tym samym namespace nową klasę WritelineValidator sprawdzającą czy pole komunikat naszej czynności jest wypełnione jeżeli nie to ma się na ikonce naszej czynności zapalić czerwony wykrzyknik i pojawić błąd przy kompilacji. public class WritelineValidator : ActivityValidator public override ValidationErrorCollection Validate(ValidationManager manager, object obj) if (null == manager) throw new ArgumentNullException("manager"); if (null == obj) throw new ArgumentNullException("obj"); ValidationErrorCollection errors = base.validate(manager, obj); WritelineActivity act = obj as WritelineActivity; if (null!= act) if (null!= act.parent) if (string.isnullorempty(act.komunikat)) errors.add(validationerror.getnotsetvalidationerror("komunikat")); return errors;

Tak zdefiniowany validator należy załączyć do naszej klasy czynności: [ActivityValidator(typeof(WritelineValidator))] public partial class WritelineActivity : SequenceActivity public WritelineActivity() InitializeComponent();... Skompilować i usunąć ewentualne błędy. Aby sprawdzić jak wygląda i działa nasza czynność utworzymy w istniejącym solution nowy projekt typu Workflow->Sequential Workflow Console Application (jest to projekt z założoną aplikacją konsolowa hosta i pustym szablonem workflow). Na Toolbox ie prawym przyciskiem myszy aktywujemy menu kontekstowe i wybieramy AddTab tworząc nowa zakładkę kontrolek o nazwie np. moje kontrolki. Następnie w ramach tej zakładki podobnie wybieramy Choose Items - > zakładka Activities. Za pomocą Browse wskazujemy położenie pliku dll zawierającego naszą czynność ->OK. Nacza kontrolka czynności została dodana do listy kontrolek w toolbox ie pod nazwą WritelineActivity. Po przeciągnięciu jej do pustego workflow otrzymujemy postać: Teraz zajmiemy się sposobem w jaki nasza czynność ma być prezentowana graficznie wracamy do projektu kontrolki WritelineActivity: Ponieważ korzystamy z gradientu liniowego należy dodać w jej kodzie namespace System.Drawing.Drawing2D; oraz klasę definiującą jej postać graficzną w oknie szablonu workflow. public class WritelineTheme : ActivityDesignerTheme ///<summary> /// tworzy temat i ustawia mu pewne wartości ///</summery> ///<param name="theme"></param> public WritelineTheme(WorkflowTheme theme) : base(theme) this.bordercolor = Color.Green; this.backcolorstart = Color.Yellow; this.backcolorend = Color.Orange; this.backgroundstyle = LinearGradientMode.ForwardDiagonal;

[ActivityDesignerTheme(typeof(WritelineTheme))] public class WritelineDesigner : ActivityDesigner Należy jeszcze związać klasę WritelineDesigner z nasza klasą czynności : [ActivityValidator(typeof(WritelineValidator))] [Designer(typeof(WritelineDesigner))] public partial class WritelineActivity: SequenceActivity Skompilować dll kę, przejść do projektu workflow konsole application i zobaczyć jak teraz prezentuje się nasza kontrolka w oknie projektanta workflow. Powinna wyglądać tak: Zadanie 2 utworzenie workflow akceptacji kredytów Opis procesu biznesowego akceptacji kredytów: Klient podaje następujące dane: kwote kredytu (w PLN) jaką chciałby otrzymać swój wiek symbol waluty w jakiej ma być udzielony kredyt (np. USD, EUR, PLN) na ile lat chciałby wziąść kredyt Kredytodawca ma przykładowo 2 minuty aby rozpatrzyć wniosek albo zdąży go rozpatrzyć albo informuje kredytobiorcę, że czas założony na rozpatrzenie wniosku minął.rozpatrzenie wniosku polega na analizie danych wejściowych i ocenie stopnia ryzyka związanego z udzieleniem kredytu w następujący sposób. Osoby ponizej (<=) 20 roku życia mogą uzyskać kredyt wyskości max 10 000 PLN. Następuje sprawdzenie jakiej kwoty żąda kredytobiorca. Jeżeli kwota żądana > 10000 PLN to ustawiany jest komunikat o odrzucieniu kredytu nie spełnienie wymogów kredytowania i wypisywana jest na konsolę informacja Jestś za młody na tak dużą kwotę. Jeżeli kwota żądana <= 10 000 PLN to sprawdzamy czy przypadkiem kilient nie chce aby kredyt został udzielony w obcej walucie. Jeżeli w obcej walucie to należy uzyskać wartość przelicznika dla danej waluty (z WebService) i wyliczyć kwotę żądanego kredytu w danej walucie. Na bazie kwoty żadanego kredytu (odpowiednio w PLN lub obcej walucie) i zakładanego okresu spłaty (w latach) wyliczana jest rata miesięczna do spłacania. Generowany jest komunikat do kredytobiorcy o pomyślnym rozpatrzeniu wniosku kredytowego. Osoby starsze (wiek>20 lat) otrzymują komunikat o odrzucieniu kredytu nie spełnienie wymogów kredytowania i wypisywana jest na konsolę informacja jesteś powyżel limitu wiekowego Klient otrzymuje następujące informacje zwrotne: Komentarz czy przydzielono czy nie kredyt; Kwota_kredytu_w_walucie Symbol waluty Żadana_kwota kredytu w PLN wiek Okeres_na ile lat wziął kredyt

Wysokość wyliczonej raty kredytu (w pln lub w zadanej walucie na wejściu) Status przydzielenia kredytu Kroki do wykonania: W projekcie typu Workflow->Sequential Workflow Console Application usuwamy naszą testowo wstawioną kontrolkę WritelineActivity i modyfikujmy program hosta (plik program.cs) o: wczytanie od kredytobiorcy wartości wejściowych przekazanie ich jako kolekcje parametrów do instancji workflow zwrócenie i wypisanie na konsole parametrów wyjściowych instancji workflow Powinien przyjąć postać: static void Main(string[] args) try //zdefiniowanie i wczytanie wartości startowych dla instancji workflow double kwota_kr = 0; int wiek = 0; int okres = 0; Console.WriteLine("podaj parametry dla wykonania workflow przydziału kredytu "); Console.Write("kwota kredytu w PLN:"); double.tryparse(console.readline(), out kwota_kr); Console.Write("wiek:"); int.tryparse(console.readline(), out wiek); Console.Write("symbol waluty w jakiej ma być udzielony kredyt:"); string waluta = Console.ReadLine(); Console.Write("na ile lat brany kredyt: "); int.tryparse(console.readline(), out okres); //utoworzenie kolekcji parametrów Dictionary<string, object> parametry = new Dictionary<string, object>(); parametry.add("kwota_kredytu", kwota_kr); parametry.add("wiek", wiek); parametry.add("okres", okres); parametry.add("symbol_waluty", waluta); //powołanie do życia runtime u i podpięcie funkcji obsługi zdarzeń utworzono, zakończono pomyślnie i zakończono z błędem wykonanie workflow using (WorkflowRuntime workflowruntime = new WorkflowRuntime()) Console.WriteLine("Runtime Started."); AutoResetEvent waithandle = new AutoResetEvent(false); workflowruntime.workflowcompleted += delegate(object sender, WorkflowCompletedEventArgs e) waithandle.set(); Console.WriteLine("parametry wyjściowe z workflow daj kredyt"); //kolekcja ta zawiera wszystkie publiczne właściwości zdefiniowane w workflow foreach (KeyValuePair<string, object> par in e.outputparameters) Console.WriteLine("0 =1", par.key, par.value); Console.ReadLine(); ; workflowruntime.workflowterminated += delegate(object sender, WorkflowTerminatedEventArgs e) Console.WriteLine(e.Exception.Message); Console.ReadLine(); waithandle.set(); ; //powołanie do życia instancji workflow i przekazanie kolekcji parametrów

//typeof(namespace.nazwa_klasy z pliku workflow1.cs definiującego szablon naszego workflow) WorkflowInstance instance = workflowruntime.createworkflow(typeof(workflowconsoleapplication1.workflow1), parametry); //uruchomienie wykonywania instancji instance.start(); // Wait for the event to be signaled waithandle.waitone(); workflowruntime.stopruntime(); Console.WriteLine("Program Complete."); Console.ReadLine(); catch (Exception exception) Console.WriteLine("Exception occured: " + exception.message); Console.ReadLine(); Teraz kolej na zdefiniowanie naszego workflow przez kolejne umieszczanie elementów z toolboxa i definiowanie ich właściwości: 1. Ponieważ nasz workflow ma się zakończyć gdy minie określony czas lub też dokonamy rozpatrzenia wniosku w czasie krótszym więc dodajemy czynność ListenActivity (każda z gałęzi musi zawierać czynność sterowaną zdarzeniem). W lewej gałęzi zdefiniujemy: oczekiwanie na upłynięcie czasu maksymalnego (2 minuty) delayactivity TimeoutDuration = 00:02:00, w którym to powinien być rozpatrzony wniosek czynność Code, dla której ustawimy pole name = powiadomienie, ExecuteCode= minal_czas (jest to przypisanie funkcji jaka ma się wykonać na wołanie metody ExecuteCode dla tej czynności)- zostanie utworzony w kodzie szablon tej metody tworzymy zawartość metody minal_czas ustawiającej zawartość informacji w polu komunikat private void minal_czas(object sender, EventArgs e) komentarz = "Minął czas przewidziany na udzielenie odpowiedzi - przepraszamy - zapraszamy ponownie "+ Status.ToString(); Ustawmy w kodzie naszego szablonu workflow (plik Workflow1.cs) wszystkie pola publiczne potrzebne do przechowywania przekazywanych parametrów wejściowych i umieszczenia parametrów wyjściowych public sealed partial class Workflow1: SequentialWorkflowActivity private int _wiek; private double _kwota_kredytu; private int _okres; private double _rata; private string _symbol_waluty; private string _komentarz; private double _kwota_kredytu_wal; [CategoryAttribute("Parameters")] public double kwota_kredytu_wal get return this._kwota_kredytu_wal; set this._kwota_kredytu_wal = value;

public string komentarz get return this._komentarz; set this._komentarz = value; public string symbol_waluty get return this._symbol_waluty; set this._symbol_waluty = value; public double kwota_kredytu get return this._kwota_kredytu; set this._kwota_kredytu = value; public int wiek get return this._wiek; set this._wiek = value; public int okres get return this._okres; set this._okres = value; public double rata get return this._rata; set this._rata = value; private StatusType statusvalue; public enum StatusType None, Approved, Rejected public StatusType Status get return this.statusvalue; set this.statusvalue = value; public double przelicznik_waluty; public Workflow1() InitializeComponent(); Status = StatusType.None; 2. W prawej gałęzi umieścimy również czynność delay z minimalnym czasem opoźnienienia = 1 sek oraz naszą własną kontrolkę WritelineActivity z komunikatem tu będzie akceptacja kredytu Powinniśmy otrzymać postać :

sprawdźmy jej wykonanie: 3. Teraz zajmiemy się analizą danych wejściowych podanych przez kredytobiorcę. Na początek w czynności IfElse sprawdzimy wiek kredytobiorcy. Umieszczamy czynność IfElse zamiennie za naszą WritelineActivity1. Zmieniamy jej nazwę w polu Name na wiek1. Dla ifelsebranchactivity1 modyfikujemy nazwe na mniej_niż20 pole Condition na CodeCondition i po rozwinięciu +Condition ustawiamy w polu Condition nazwę metody na sprawdz_wiek, która będzie definiować i sprawdzać warunek wejścia do lewej gałęzi. Szablon metody zostanie wygenerowany uzupełniamy go do postaci: private void sprawdz_wiek(object sender, ConditionalEventArgs e) e.result = (wiek <= 20); Warunku dla drugiej gałęzi IfElse nie ustawiamy działa domyślnie jak ELSE 4. W gałęzi ELSE czyli warunek wiek>20 umieścimy dwie czynności: Code nazwę zmieniamy na odmowa2 a pole ExecuteCode= odrzuc_kredyt

private void odrzuc_kredyt(object sender, EventArgs e) Status = StatusType.Rejected; komentarz = "Bardzo nam przykro ale nie spełnia Pan/Pani warunków kredytowania \n" + Status.ToString(); WritelineActivity z komunikatem jesteś powyżej limitu wiekowego Bieżąca postać workflow akceptacji wniosku kredytowego: 5. Uzupełnimy teraz lewą gałąź IfElse dla warunku wiek<=20. Należy umieścić kolejną czynność IfElse dla sprawdzenia czy zadana kwota kredytu <=10000. Ustawiamy dla niej Name = kwota_kred, i w lewej gałęzi dla ifelsebranchactivity1 name = mniej10tys oraz Condition=Code Condition, +Condition= spr_zadana_kwote private void spr_zadana_kwote(object sender, ConditionalEventArgs e) e.result = (kwota_kredytu <= 10000); W prawej gałęzi czynności (tj. kwota kredytu >10000) umieszczamy czynność code odmowa1 (wykonuje metodę odrzuc_kredyt) i WritelineActivity2 z komunikatem jesteś młody i chcesz zbyt dużą kwotę. Bieżąca postać to:

6. Teraz zajmiemy się lewą gałęzią - kwota kredytu <=10000. Z punktu biznesowego nie ma tu przeciwwskazań do udzielenia kredytu mimo, iż wiek jest młody to kwota jest niska i kredytodawca jest w stanie ponieść takie ryzyko. Zanim jednak obliczymy ratę kredytu i przyznamy go należy sprawdzić, czy czasem klient nie chce go uzyskać w walucie obcej a jeżeli tak to należy pozyskać przelicznik tej waluty. Umieszczamy kolejnego IfElse o nazwie w_walucie - z warunkiem spr_walute i nazwą warunku obca: private void spr_walute(object sender, ConditionalEventArgs e) e.result = (symbol_waluty.toupper()!= "PLN"); 7. Jeżeli mamy do czynienia z walutą obcą to wykorzystamy usługę sieciową do pozyskania przelicznika. Usługa dostępna pod adresem: http://www.webservicex.net/wcf/servicedetails.aspx?sid=18 Umieścimy w tym celu czynność InvokeWebService, wskazać powyższy adres w polu URL, kliknąć GO, dodać referencje webową o proponowanej nazwie. We właściwościach ustawić MethodName= ConversionRate. Dla pola FromCurrency double-click na żółtej ikonce właściwości wiązanej ->zakładka Bind to a new member -> Create Field utworzymy sobie nowe pole związane z tą właściwością o nazwie invokewebserviceactivity1_fromcurrency1 i potem podstawimy do niego odpowiednią wartość. W kodzie zostanie wygenerowany zapis: public WorkflowConsoleApplication3_usun.net.webservicex.www.Currency invokewebserviceactivity1_fromcurrency1 = new WorkflowConsoleApplication3_usun.net.webservicex.www.Currency(); Powtarzamy te czynności również dla pola ToCurrency tworząc pole związane invokewebserviceactivity1_tocurrency1 oraz dla (ReturnValue) wybieramy z okna bind to existing member pole przelicznik_waluty.

W kodzie odpowiednio: public WorkflowConsoleApplication3_usun.net.webservicex.www.Currency invokewebserviceactivity1_tocurrency1 = new WorkflowConsoleApplication3_usun.net.webservicex.www.Currency(); Teraz ustawimy dla pola Invoking nazwę metody, która ma być wykonana przed wywołaniem usługi. U nas Invoking = przypisz_wartosci zostanie utworzony szablon dla niej, który uzupełniamy do postaci: private void przypisz_wartosci(object sender, InvokeWebServiceEventArgs e) invokewebserviceactivity1_fromcurrency1 = WorkflowConsoleApplication1.net.webservicex.www.Currency.PLN; switch (symbol_waluty.toupper()) case "USD": invokewebserviceactivity1_tocurrency1 = WorkflowConsoleApplication1.net.webservicex.www.Currency.USD; break; case "EUR": invokewebserviceactivity1_tocurrency1 = WorkflowConsoleApplication1.net.webservicex.www.Currency.EUR; break; default: break; Gdzie WorkflowConsoleApplication1 jest namespacem, w którym jest szablon workflow i referencja (o nazwie net.webservicex.www) do definicji typu wyliczeniowego waluty -Currency 8. Teraz należałoby wyliczyć wartość kredytu w żądanej przez klienta walucie umieszczamy pod wołaniem usługi sieciowej kolejną czynność typu Code o nazwie kredyt_w_walucie2 i przypisujemy jej wykonanie metody kredyt_w_walucie o postaci: private void kredyt_w_walucie(object sender, EventArgs e) this.kwota_kredytu_wal = this._kwota_kredytu * przelicznik_waluty; 9. Na koniec należy wyliczyć ratę kredytu i poinformować o przyznaniu kredytu. jest to kontynuacja lewej gałęzi od czynności warunkowej o nazwie kwota_kredytu2 ale już poza warunkiem sprawdzającym walutę. Dodajemy czynność Code o nazwie wylicz_rate1 i przypisujemy jej wykonanie metody wylicz_rate o postaci: private void wylicz_rate(object sender, EventArgs e) if (symbol_waluty.toupper() == "PLN") rata = kwota_kredytu / (okres * 12); else rata = kwota_kredytu_wal / (okres * 12); Dodajemy czynność Code o nazwie przyznanie i przypisujemy jej wykonanie metody przyznaj_kredyt o postaci: private void przyznaj_kredyt(object sender, EventArgs e) Status = StatusType.Approved; komentarz = "Gratulujemy kredyt został przyznany " + Status.ToString(); 10. Otrzymana postać szablonu workflow dla rozpatrywania kredytu według przyjętego opisu procesu biznesowego ma postać:

Przeanalizować działanie spróbować zmodyfikować aplikacje hosta i uruchomić wiele instancji tego workflow. Rozwinięcie procesu biznesowego zadanie indywidualne (Poniższy opis modyfikuje proces w zakresie wiek>20 lat) Osoby powyżej (>) 20 roku życia mające miesięczny zarobek <=3500 PLN mogą uzuskać kredyt w kwocie max 50 000 PLN, a o zarobku >3500 PLN max 80 0000 PLN. W pozostałych przypadkach wołany jest ekspert indywidualnie oceniającego stopień ryzyka i podejmującego decyzję o przyznaniu lub odrzuceniu kredytu. Ekspert ma max 1 dzień na dokonanie ekspertyzy. Osobom powyżej 80 roku życia kredyt nie przysługuje (otrzymują komunikat o odrzucieniu kredytu nie spełnienie wymogów kredytowania i wypisywana jest na konsolę informacja jesteś powyżel limitu wiekowego )

Przykład zaimplementowania experta bankowego jako własnego Runtime Service komunikującego się z daną instancja workflow. Do definicji pól w Workflow1.cs dodać; private double miesieczny_zarobek; public double Miesieczny_zarobek get return miesieczny_zarobek; set miesieczny_zarobek = value; oraz definicję interfejsu experta bankowego (poza klasą Workflow1 ale w tym samym namespace) [ExternalDataExchange] public interface IExpertBankowy void ocenexperciewniosek(double kwota,double mies_zar); event EventHandler<ExternalDataEventArgs> opiniaexperta; Dodaj do projektu nowy plik klasy ExpertBankowy.cs oraz definicje klas przekazywanych argumentów między instancja, a hostem public class ExpertBankowy : IExpertBankowy public event EventHandler<ExternalDataEventArgs> opiniaexperta; public void ocenexperciewniosek(double kwota, double mies_zar) ThreadPool.QueueUserWorkItem(GetResponse, new ocenwniosekeventargs(workflowenvironment.workflowinstanceid, kwota, mies_zar)); private void GetResponse(object o) ocenwniosekeventargs args = o as ocenwniosekeventargs; double podzial = args.kwota/ args.mies_zar; Console.WriteLine("kwota przez zarobek wynosi" + podzial +"czy chcesz zatwierdzić pozyczkę? " ); // read the user's response from the command line char response = Console.ReadKey().KeyChar; Console.WriteLine(); // check the user's response // and raise the appropriate event if (response == 'y') opiniaexperta(null, new opiniaeventargs(args.instanceid,true)); else opiniaexperta(null, new opiniaeventargs(args.instanceid, false)); //def parametrów przekazywanych do metody usługi związanej wołanej z wewnątrz workflow [Serializable] public class ocenwniosekeventargs : ExternalDataEventArgs private double _kwota; public double Kwota

get return _kwota; set _kwota = value; private double _mies_zar; public double Mies_zar get return _mies_zar; set _mies_zar = value; public ocenwniosekeventargs(guid instanceid, double _mies_zar, double kwota) :base(instanceid) this._kwota = kwota; this._mies_zar = _mies_zar; //def parametrów przekazywanych z serwisu do wewnątrz workflow za pomocą generowanego zdarzenia (na które nasłuchujemy w workflow) [Serializable] public class opiniaeventargs : ExternalDataEventArgs private bool _przyznano; public bool Przyznano get return this._przyznano; public opiniaeventargs(guid instanceid, bool _przyznano) : base(instanceid) this._przyznano = _przyznano; W pliku program.cs należy dopisać pobranie z klawiatury kwoty miesięcznego zarobku kredytobiorcy: double zarobek = 0; Console.Write("twoj miesieczny zarobek:"); double.tryparse(console.readline(), out zarobek);... parametry.add("miesieczny_zarobek", zarobek); W tym samym pliku zanim powołamy do życia instancję naszego workflow należy dodać do usług naszą usługę experta bankowego ale jako usługę typu ExternalDataExchangeService //dodamy usługę do wymiany komunikacji do/z instancją workflow ExternalDataExchangeService edes = new ExternalDataExchangeService(); workflowruntime.addservice(edes); ExpertBankowy expertb = new ExpertBankowy(); edes.addservice(expertb); Teraz należy zmodyfikować nasz szablon workflow dodając w gałęzi warunku wieku między 20 a 80 CallExternalMethodActivity w celu wywołania metody ocenexperciewniosek z naszego serwisu ExpertBankowy. Należy dla niej wybrać InterfaceType -> IExpertBankowy, methodname= ocenexperciewniosek, oraz związać właściwość mies_zar z polem Miesięczny_zarobek (z naszego Workflw1) i kwota z kwota_kredytu (z naszego Workflow1). (patrz rys. poniżej)

Przekazaliśmy wniosek kredytowy do oceny eksperta bankowego teraz należy oczekiwać na jego odpowiedź. Dajemy mu 1 dzień na dokonanie ekspertyzy. Należy więc wstawić jako kolejną czynność nasłuchującą na zaistnienie zdarzenia ListenActivity (wykona się jedynie pierwsze zaistniałe zdarzenie). W jednej gałęzi dajemy DelayActivity z 1 dniem oczekiwania ( TimeoutDuration = 1.00:00:00) i informację o tym, że minął czas dla odpowiedzi eksperta wniosek kredytowy w statusie none. W drugiej gałęzi oczekujemy za pomocą HandleExternalEventActivity na nadejście powiadomienia od experta o dokonanej ekspertyzie z parametrów tego zdarzenia należy odczytać jaka zapadła decyzja (przyznany czy nie). Ustawiamy dla niej nazwę = czekaj_odpexperta, InterfaceType na

IExpertBankowy oraz EventName = opiniaexperta. Ustawiamy też nazwę metody jaka ma się wykonać po nadejściu zdarzenia (Invoked = przyszła_odp_exp). W kodzie tej metody sprawdzimy jaka jest nadesłana odpowiedź i ustawimy odpowiednio status dla kredytu. private void przyszła_odp_exp(object sender, ExternalDataEventArgs e) opiniaeventargs a = e as opiniaeventargs; if (a.przyznano) Status = StatusType.Approved; else Status = StatusType.Rejected; Console.WriteLine("Odpowiedź experta o przyznaniu kredytu: " + Status.ToString()); Zdebagować projekt Ogólny widok na układ projektu: