Tworzenie aplikacji wykorzystujących Workflow Foundation oraz Windows Presentation Foundation Prezentacja będzie miała na celu pokazanie praktycznych aspektów zastosowania Windows Presentation Foundation i Workflow Foundation. Zaprezentowany zostanie szkielet aplikacji, w której połączone będą różne technologie, tak aby słuchacze byli w stanie samodzielnie ocenić przydatność poszczególnych rozwiązań. Dodatkowo omówione będą mechanizmy pozwalające łączyć Windows Forms i WPF. Tomasz Kopacz
Plan Omówienie kluczowych cech .NET 3.0 (WF + WPF) Budowa systemu do przyjmowania zgłoszeń i ich obsługi Logika w WF Hosting jako usługa Web Klienci napisani w WPF
Używane technologie .NET 3.0, „następca” Win32, przeznaczony tylko dla kodu zarządzalnego: (dawniej WinFX) Windows Workflow Foundation (WF) Maszyna stanów + sekwencje + DESIGNER Windows Presentation Foundation (WPF) „Wektorowe” Windows Forms Deklaratywny UI; XAML; inna filozofia i architektura
Windows Workflow Foundation (WF) (Szybki) przegląd kluczowych cech
Windows Workflow Foundation Jedna technologia workflow na Windows Łatwo rozszerzalna Framework zarówno do budowy systemowych (automatycznych) przepływów jak i tych sterowanych przez człowieka (wybór; UI itp.) Nie jest to serwer - framework, API, DLL Serwer można zbudować Przykład: SharePoint 3.0 + klient Office 2007 W środku: „Tylko” maszyna stanu + sekwencje +Designer (też do osadzenia we własnej aplikacji ) Lub XAML +Usługi
WF – podstawowe pojęcia Diagram stanów…. Activity (Aktywność) Wykonywana operacja w danym systemie EscalateToManager CheckInventory Gotowe: Wywołaj kod, usługę Web,… 2 typy definicji przepływów: Orkiestracja (Diagram przepływów) Diagram stanów + zdarzenia Modele można łączyć/mieszać Reguła (Rule) – parametryzuje Host - uruchamia przepływ Używa usług (Runtime Services) „Zaplecze” usługowe: transakcje, stan… Przepływ działa w ODDZIELNYM wątku Specjalna komunikacja Definicja przepływu Maszyna stanów + zdarzenia Orkiestracja Modele można łączyć/mieszać Activity (Aktywność) Wykonywana operacja EscalateToManager CheckInventory Gotowe: Wywołaj usługę Web,… Do napisania dla danego systemu Reguła (Rule) Reguła powiązana z czynnością Definiuje m. innymi policy Host Używając motoru WF uruchamia przepływ Usługi (Runtime Services) „Zaplecze” usługowe: transakcje, stan itp.. Diagram przepływów….
Przepływ = Kod Tylko znaczniki Znaczniki + kod Tylko kod XAML XAML C#/VB C#/VB Kompilator przepływu Tylko znaczniki Drzewo obiektów XAML Kompilator C#/VB XOML 2 typy Maszyna stanów sterowana zdarzeniami Przepływ/Orchestration/workflow Kolejność i zasady wywoływania kolejnych aktywności Można łączyć/mieszać Instancja przepływu Assembly
Usługi Workflow Gotowe: Zapis stanu (SqlWorkflowPersistenceService) Śledzenie (SqlTrackingService) Scheduler (DefaultWorkflowSchedulerService) Punkty zachowania/transakcje WorkflowCommitWorkBatchService SharedConnectionWorkflowCommitWorkBatchService Schematy bazy: C:\WINDOWS\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\EN Dodawanie „usługi” z której workflow może skorzystać workflowRuntime.AddService(instancja) Też własne – np. wymiana zdarzeń Z poziomu aktywności: executionContext.GetService<typ>()
Obsługa zgłoszeń serwisowych Obsługa i wykorzystanie przepływu Duże DEMO Obsługa zgłoszeń serwisowych Obsługa i wykorzystanie przepływu
Scenariusz System zgłoszeń serwisowych Zgłoszenie to: Świadczone usługi Klient ma pewien kredyt Zgłoszenie to: Tytuł/opis Priorytet Używany do wyliczenia opłaty Ostatecznie będzie (albo): Zaakceptowane Przetworzone Odrzucone Proces (przyjęcie) Weryfikacja środków Rezerwacja Akceptacja/Odrzucenie Kategoryzacja Przekazanie do serwisanta Wizyta lub Raport postępów przy pracy zdalnej Wycena (zdjęcie środków; zwolnienie rezerwacji) Zakończenie
Diagram Diagram
I jak to wszystko testować… Kilka pytań Jak i gdzie uruchamiać przepływ? Jak się z przepływem komunikować? Co jeżeli nagle motor „padnie” a zgłoszenie już zdążyło zarezerwować środki? Jak pobrać „wyliczoną” kwotę do akceptacji? I jak tą kwotę wyliczyć? I jak to wszystko testować…
Prosty hosting Interfejs: IAdd, int Add(int a, int b); Przepływ WebServiceInputActivity – używa sygnatury Add <operacje> WebServiceOutputActivity – wynik „Publish As Web Service” Klient – dodaje referencje do usługi Web DEMO SimpleWorkflow_WebService <- pokazać web.config SimpleWorkflow SimpleWorkflowTest Może wypaść demo
Problemy Hosting – wolę mieć pełną kontrolę Komunikacja z klientem W tym przypadku: Własne ASP.NET W środku uruchamiane Runtime Komunikacja z klientem WS (naturalny wybór) Komunikacja Workflow – host Interfejs z potrzebnymi operacjami Z poziomu przepływu: HandleExternalEvent Zdarzenie zgłaszane, zmiana stanu, akceptacja CallExternalMethod Gdy Workflow ma o czymś poinformować hosta (wyliczona kwota) Z poziomu hosta: Implementacja interfejsu i rejestracja go jako usługi
Uwagi o konstrukcji przepływu DependencyProperty Część modelu komponentu w .NET 3.0 Kontekst, „rozpoznawanie wartości” Validacja, powiadamianie itp. „Doklejanie” do obiektu WPF: Potem łatwe związywanie z parametrem w designerze Transakcja a kompensacja Punkty zapisu Przerywanie przepływu Abort (da się wznowić) Terminate (kasuje) Zasada liczenia kwoty Policy + reguły (to się NA PEWNO będzie często zmieniać)
DEMO Analiza przepływu Omówienie Common – wymiana danych Obsługa transakcji Kompensacja
Hosting + Testowanie przepływu Hosting (I) - DEMO Hosting + Testowanie przepływu Omówienie DataModel – Dane przekazywane do/z klienta Omówienie MyRuntimeHost – klasa opakowująca workflow Runtime Omówienie MyRuntimeHostTest – testowanie Omówienie WF_HOST – usługa Web
Windows Presentation Foundation Projekt i organizacja UI
Projekt i organizacja UI Założenie: używamy WPF, ale piszemy „jak w WinForms” Dwie aplikacje Administrator (używa tylko WS) lista aktywnych przepływów + lista zdarzeń User (WS + normalne bindowanie do tabelki) Dodanie nowego Mamy coś w WinForms i chcemy to użyć Przyciski do zmiany stanu Odpytywanie WS o „aktualny stan” Blokowanie/odblokowywanie kontrolek
WPF Podstawy podstaw <Window x:Class="obiekt" … <Button Name ="button1" Click="bC”>Kliknij</Button> … private void bC(Object sender, RoutedEventArgs e) {…} Rozdzielona „definicja UI” i obsługa XAML + code behind Ale – przekształcane do CS/VB.NET XAML: Szybsze niż GDI+ (logiczne a wizualne drzewo) Dużo nowych możliwości Obiekty 2D i 3D, kontrolki, okna, pojemniki automatycznie „rozkładające” zawartość Transformacje 2D/3D (skalowania/obroty) XPS Animacje; wideo (transformacje itp.) Rozmiary metryczne Pixel w WPF = 1/96 cala Nie ma wszędzie „uchwytu okna” Wiele wątków! DispatcherObject.VerifyAccess Kontrolka: model MVC Wizualizator określa JAK wygląda Style RoutedEventHandler
Wizualizatory i wzorce <Style TargetType= "{x:Type TextBox}"> <Setter Property="Background" Value="Green " /> </Style> … <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="… "> <Border x:Name="Bd"> <Style.Triggers> <Trigger Property="IsEnabled" Value="true"> <Setter Property="… " Value="Bold"/> … <Style x:Key="MainTextBox"></Style> Styl Do typu lub nazwany Lub „cecha” obiektu Ustawia właściwości Czcionka, kolory - wszystko Kontekst! Template – „przepis na rysowanie”
Data Binding Składnia w XAML Ręcznie kontekst <DataTemplate x:Key="MyItemTempl"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width=… <TextBlock Text= "{Binding Path=Title}" Grid.Column="0" FontWei…/> <TextBlock Text="{Binding Path=FirstName}" Grid.Column="1" /> <TextBlock Text="{Binding Path=LastName}" Grid.Column="2" /> Składnia w XAML {Binding Source={StaticResource my}, Path=ColorName} Text="{Binding Path=Title}" Ręcznie kontekst Kontrola kiedy zmiany są propagowane <ValidationRules> DataTemplate – jak prezentować rekord ListBox itp. Specjalizacje (ListView) Bez OnChanged… i de facto layzy binding <DataTemplate x:Key="MyItemTemplate"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="50"/> </Grid.ColumnDefinitions> <TextBlock Text="{Binding Path=Title}" Grid.Column="0" FontWeight="Bold" /> <TextBlock Text="{Binding Path=FirstName}" Grid.Column="1" /> <TextBlock Text="{Binding Path=LastName}" Grid.Column="2" /> </Grid> </DataTemplate>
WPF a Windows Forms WinFormw w oknie WPF WPF w oknie WinForms <WindowsFormsHost Name="wfHost" DockPanel.Dock="Top" Height="300"> <mcl: AddRequest1 Name="mc"/> </WindowsFormsHost> … AddRequest r = new AddRequest(); r.uxClient.DataSource = dt; wfHost.Child = r; Przekazywanie zdarzeń, kontekstu bindingu Ustawianie globalnych „cech” z poziomu pojemnika Wielkość czcionki itp Nie zapomnieć o referencji: WindowsFormIntegration WinFormw w oknie WPF ctrlHost = new ElementHost(); ctrlHost.Dock = DockStyle.Fill; panel1.Controls.Add(ctrlHost); avAddressCtrl = new MyControls.Page1(); avAddressCtrl.InitializeComponent(); ctrlHost.Controls.Add(avAddressCtrl); avAddressCtrl.OnButtonClick += ... WPF w oknie WinForms
DEMO Interfejs administratora Interfejs użytkownika Hostowanie WinForms w WPF
DEMO Zmiana – po zakończeniu prac zdalnych, ma być wizyta a potem weryfikacja Zmienić OnRequestProcessed Z Verification na Visited State Ew restart Vs.NET
Podsumowanie Workflow Foundation – REWELACJA WPF Ale – trzeba pamiętać że to ODDZIELNY proces Komunikacja, synchronizacja itp. Duża elastyczność Łatwe modyfikacje logiki Trochę trudniejsze pisanie UI Nie należy „przesadzić” z uniwersalnością UI – czas/elastyczność WPF Duże możliwości Ale trzeba wymyślić jak użyć Ale można „pisać” podobnie jak w WinForms Łatwiej niż w WinForms można „generować” odpowiednie struktury Automatyczne rozkładanie zawartości, pojemniki, sensowny routing zdarzeń…
Uwagi o programowaniu i problemach DTC lokalny musi działać SharedConnectionWorkflowTransactionService Uwagi końcowe TO TYLKO PRZYKŁAD Dlaczego w ogóle klient komunikuje się z bazą danych? Obsługa błędów Nie analizować FXCOP ... Skąd informacje: Blogi, grupy dyskusyjne, wyszukiwarka
Tomasz Kopacz, tkopacz@tomaszkopacz.com Dziękuję za uwagę Tomasz Kopacz, tkopacz@tomaszkopacz.com