Tìm hiểu mô hình và công nghệ wf 4.0

I. Tổng quan về mô hình luồng công việc. 1. Luồng công việc: 2. Sự thực thi các LCV 3. Tầm quan trọng trong việc đưa LCV và Mô hình LCV vào ứng dụng. 4. Đặc điểm: 5. Kiến trúc cơ bản của WF. 5.1 Activity và Custom Activity. 5.2 WF Runtime. 6. XAML: 7. Sự lưu trú của WF trên ứng dụng:. II. Window WorkFlow Foudation 4.0. 1. Ứng dụng workflow đơn giản đầu tiên với WF4. 2. Làm việc với các Activity được xây dựng sẵn. If Activity. Assign activity. While activity. Kết quả thu được khi chạy ứng dụng workflow trên: 23 3. Xây dựng workflow bằng code. Xây dựng ứng dụng workflow bằng code C#. Expression. Variables. 4.Xây dựng Flowchart workflow: FlowDecision activtity. FlowSwitch<T> activity. 5.Arguments : Tạo workflow project mới Định nghĩa Arguments cho workflow Một số activities trong namespace System.Activities.Expressions. Đưa Arguments vào workflow và chạy workflow 6. Xây dựng custom activity: Kế thừa từ Activity<TResult> Kế thừa từ CodeActivity<TResult>

doc41 trang | Chia sẻ: lvcdongnoi | Lượt xem: 3460 | Lượt tải: 1download
Bạn đang xem trước 20 trang tài liệu Tìm hiểu mô hình và công nghệ wf 4.0, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
TRƯỜNG ĐẠI HỌC SƯ PHẠM KĨ THUẬT THÀNH PHỐ HỒ CHÍ MINH KHOA CÔNG NGHỆ THÔNG TIN BỘ MÔN CÔNG NGHỆ PHẦN MỀM TÌM HIỂU MÔ HÌNH VÀ CÔNG NGHỆ WF 4.0 GVHD: NGUYỄN MINH ĐẠO SVTH: NGUYỄN HỮU TRUNG 07110144 NGUYỄN HỮU TÀI 07110108  NGUYỄN HỮU THANH 07110116   NGUYỄN VĂN PHONG 07110089  NGUYỄN PHÚ CƯỜNG 07110019 THÁNG 11/2011 Contents Tổng quan về mô hình luồng công việc Luồng công việc: Vào những năm tám mươi của thế kỷ hai mươi, khái niệm luồng công việc (Workflow) mới được sử dụng lần đầu tiên trong ngành công nghệ phần mềm. Tuy thế, sự xuất hiện của luồng công việc và mô hình luồng công việc trong cuộc sống của con người hẳn đã từ rất lâu. Giữa vô vàn các hoạt động của mình trong cuộc sống, có nhiều công việc mà con người lặp đi lặp lại nhiều lần. Một hoặc một số các công việc có thể được lặp lại theo chu kỳ nhiều giờ, nhiều ngày, nhiều tháng v.v… hoặc xảy ra bất kỳ lúc nào. Dựa vào kinh nghiệm đúc kết được, con người vạch ra các bước phải làm và dần dần hoàn thiện chúng cho các lần thực hiện sau. Nói khác hơn, dựa vào kinh nghiệm và sự hiểu biết của mình, con người có thể vạch ra các kế hoạch; xác định thành phần con người, cũng như công cụ cần có để thực hiện công việc nhằm đạt được mục đích nhất định. Các bước cần thực hiện trong các kế hoạch đó có mối quan hệ với nhau và tạo thành luồng công việc. Luồng công việc là một tập có thứ tự các công việc tuân theo các quy tắc nhất định, được định sẵn sao cho việc thực hiện theo đó sẽ đạt được các mục đích công việc đã đề ra. Khái niệm về luồng công việc là một khái niệm tương đối. Cùng tham gia vào một hệ thống trong cùng một môi trường, nhưng những đối tượng với vai trò khác nhau sẽ có các luồng công việc khác nhau. Hình vẽ dưới đây là ví dụ về các luồng công việc trong hệ thống tổ chức thi tuyển sinh đại học tại Việt Nam. Dưới góc nhìn của các thí sinh, luồng công việc thi tuyển sinh gồm 3 việc chính phải làm. Thực hiện luồng công việc này, các thí sinh đạt được mục đích là dự thi đại học thành công. Dưới góc nhìn của đơn vị tổ chức tuyển sinh thì lại khác, luồng công việc tổ chức thi tuyển sinh gồm có 9 công việc chính phải làm, thực hiện luồng công việc này sẽ đạt được mục đích là tổ chức thành công một kỳ tuyển sinh đại học. Hình 1. Luồng công việc Thi tuyển sinh đại học dưới góc nhìn của thí sinh Hình 2. Luồng công việc Tổ chức tuyển sinh đại học dưới góc nhìn của đơn vị tổ chức tuyển sinh Sự thực thi các LCV Ứng với một quá trình thực thi LCV là một thể hiện của LCV đó. Một LCV có thể có nhiều thể hiện khác nhau do quá trình thực thi khác nhau. Mỗi LCV khi thực thi sẽ phải tuân thủ các quy tắc nhất định. Đó là các quy định về quy trình nghiệp vụ thực tế của tổ chức, doanh nghiệp tạo ra và thực thi LCV đó như các ràng buộc về sự tương tác với người thực hiện công việc, ràng buộc về thời gian thực thi, các điều kiện cho phép xảy ra sự kiện chuyển đổi trạng thái v.v… Ngoài ra, từng công việc thành phần bên trong một LCV cũng có các ràng buộc riêng của nó trong quá trình thực thi. Ví dụ, công việc “Nhận đăng ký thi” trong ví dụ về LCV Tổ chức tuyển sinh đại học ở phần trước có thể có một số ràng buộc như: bắt đầu từ ngày t1 và kết thúc vào ngày t2; chỉ cho phép đăng ký khi các giấy tờ đều hợp lệ, thí sinh đăng ký phải tốt nghiệp trung học phổ thông trước đó, v.v… Tầm quan trọng trong việc đưa LCV và Mô hình LCV vào ứng dụng Hiện nay, trên thế giới, đã có rất nhiều ứng dụng hỗ trợ thực thi và quản lý LCV. Những ứng dụng loại này được xem là các Hệ quản trị luồng công việc (HQT LCV). Các HQT LCV ngày càng được sử dụng rộng rãi trong doanh nghiệp và ngày càng trở nên quan trọng hơn bởi: Các ứng dụng thường chỉ hỗ trợ người dùng thực hiện đúng công việc của mình. Các công việc này thường được thiết kế một cách tách biệt, giữa chúng thường không có mối quan hệ nào về thứ tự thực hiện, cũng như không có những ràng buộc quan trọng liên quan đến quy luật hoạt động của doanh nghiệp. Trên thực tế, những ứng dụng này thật sự giúp ích cho doanh nghiệp, nhưng xét cho cùng, vì nó không thể hiện được các quy luật kinh doanh thực tế của doanh nghiệp, nên ngày càng khó đáp ứng được các nhu cầu ngày càng cao của họ. Sự xuất hiện của các HQT LCV giúp giải quyết những vấn đề này. HQT LCV đồng thời hỗ trợ người dùng thực hiện công việc của mình, theo một quy luật cụ thể. Trên thực tế, các công việc được hoàn tất không độc lập với nhau mà có mối quan hệ nhất định. Công việc này phải được thực hiện trước công việc kia, để thực hiện công việc này đòi hỏi phải theo những quy định... Tất cả hoàn thành sẽ đạt được một mục tiêu nhất định. Chẳng hạn như hoàn thành việc nhận và kí hồ sơ, tổ chức thành công kì thi tuyển sinh đại học... Nó có một quy trình, một LCV cụ thể ứng với từng mục tiêu. Các LCV có thể tách biệt hoặc có trình tự thực hiện riêng... HQT LCV giúp thực thi những LCV trong doanh nghiệp, đảm bảo thứ tự và quy tắc thực hiện, đồng thời giảm thiểu những rủi ro có thể có khi thực hiện các công việc thủ công... HQT LCV đồng thời cung cấp chức năng quản lý LCV hỗ trợ người quản lý của doanh nghiệp nắm bắt tình hình hoạt động của các LCV nhanh chóng, kịp thời, nhằm đưa ra những xử lý thích hợp, giảm thiểu tình trạng gặp rắc rối mà không biết sớm dẫn đến công việc bị thất bại; vì thế cũng góp phần giảm thiểu rủi ro thực thi cho doanh nghiệp. Ngoài ra, theo thời gian, các HQT LCV được các công ty lập trình thiết kế phát triển, mở rộng nhiều tính năng nên ngày càng phù hợp với quy luật hoạt động tự nhiên của doanh nghiệp, đồng thời tăng cường tối đa sự hỗ trợ, nên ngày càng trở nên quan trọng hơn. Đặc điểm: Hiện nay, trên thế giới, có rất nhiều nền tảng công nghệ được thiết kế nhằm hỗ trợ việc xây dựng các sản phẩm mô hình hóa LCV, cũng như các phần mềm mã nguồn mở khác với mục đích tương tự. Trong đó, Windows Workflow Foundation là một nền tảng công nghệ do Microsoft nghiên cứu, xây dựng và đóng gói trong bộ .Net Framework (từ phiên bản 3.0 trở lên). WF cho phép người dùng định nghĩa, thực thi và quản lý LCV với các những điểm khác biệt so với các hệ thống khác như sau: WF cho phép điều khiển các công việc thực thi trong thời gian dài (nhiều ngày, nhiều tháng, …). WF có thể chỉnh sửa động khi đang thực thi. WF là một phương pháp lập trình khai báo kết nối các thành phần được định nghĩa sẵn (activity). WF cho phép người dùng định nghĩa các LCV. WF hỗ trợ nhiều kiểu ứng dụng khác nhau. Đồng thời, WF cũng có một số đặc điểm ưu việt sau: Cung cấp một kiến trúc mạnh mẽ và linh hoạt cho việc phát triển ứng dụng LCV Thúc đẩy sự nhất quán trong phát triển ứng dụng, giúp cải thiện năng suất trong việc tạo ra ứng dụng mới cũng như sửa chữa, nâng cấp ứng dụng cũ Cung cấp dịch vụ Persistence, cho phép thực thi LCV trong một thời gian dài. Có khả năng mở rộng vô hạn; nghĩa là Microsoft cung cấp một số điểm mở rộng cho phép chúng ta có thể sửa đổi những thuộc tính mặc định của LCV. Chẳng hạn như khi dịch vụ SQL Persistence nêu trên không đáp ứng được nhu cầu của chúng ta, chúng ta có thể tự xây dựng dịch vụ riêng của mình Kiến trúc cơ bản của WF Kiến trúc cơ bản của WF gồm có 3 thành phần chính: BAL (Base Activity Library), Runtime Engine và Runtime Services; có thể được mô tả như hình sau: Hình 3. Cấu trúc luồng công việc Activity và Custom Activity Một LCV trong WF được tạo thành từ các Activity, là các đối tượng được xây dựng sẵn tương tự các đối tượng quen thuộc (button, textbox…) trong ứng dụng dành cho Windows. Mỗi đơn vị công việc trong thực tế khi mô hình hóa sẽ thành một đối tượng Activity. Đây cũng chính là thành phần nhỏ nhất trong mô hình LCV định nghĩa bởi WF. Để xây dựng ứng dụng WF, Microsoft cung cấp một thư viện các Activity cơ bản, gọi là Base Activity Library (gọi tắt là BAL). Ngoài ra, người sử dụng có thể tự định nghĩa các Activity khác nhằm phục vụ cho nhu cầu đặc trưng của từng quy trình nghiệp vụ - gọi là các Custom Activity. Các Activity này cũng như cả LCV có thể được thiết kế, định nghĩa thông qua Workflow Designer tích hợp sẵn trong công cụ Visual Studio hoặc bằng cách viết mã XAML trực tiếp. WF Runtime Cung cấp các thành phần cơ bản để thực thi và quản lý thể hiện LCV, cung cấp chức năng trả về tình trạng thực thi của thể hiện, đồng thời lưu trú các thể hiện LCV độc lập. XAML: Ngoài cách sử dụng C# hay VB.net để định nghĩa LCV (thường được gọi là imperative definition), WF còn có khả năng thực thi LCV dựa trên declarative definition, nghĩa là định nghĩa LCV bằng ngôn ngữ Markup XML. Mỗi cách đều có những lợi điểm và nhược điểm riêng của nó. Việc sử dụng C#, VB.Net sẽ giúp chương trình thực thi nhanh hơn. Tuy nhiên, điểm yếu của nó chính là việc LCV phải được định nghĩa lúc buildtime. Nếu có sự thay đổi trong tiến trình nghiệp vụ, chương trình cần được thiết kế lại, biên dịch lại. Điều này khiến cho LCV trở nên thiếu linh hoạt. Trong khi nhu cầu thay đổi LCV đối với các doanh nghiệp ngày càng cần thiết (nhất là những doanh nghiệp có tiến trình nghiệp vụ thay đổi theo thời gian). Việc sử dụng XML để định nghĩa LCV có thể giải quyết được vấn đề này. Vì Workflow Runtime có thể chấp nhận gần như tất cả các dạng định nghĩa LCV (phụ thuộc vào người lập trình), tức là lập trình viên chỉ cần thông dịch định nghĩa LCV được cung cấp thành định dạng mà Workflow Runtime có thể hiểu và thực thi. Tuy nhiên, điều may mắn ở đây là WF hỗ trợ định nghĩa LCV sử dụng ngôn ngữ nền tảng xml (XML-based Workflow Definition), đó là XAML (Extensive Application Markung Language). Việc định nghĩa LCV theo cấu trúc xml giúp LCV có thể dễ dàng được sửa đổi và triển khai. Thay vì phải biên dịch lại trong Visual Studio, người dùng chỉ cần chỉnh sửa lại file định nghĩa LCV bằng bất kì trình Editor nào (ngay cả notepad), và đưa vào Workflow Runtime trước khi nó tạo lại mô hình LCV. XAML ban đầu được đưa vào sử dụng trong WPF (Windows Presentation Foundation, một công nghệ được Microsoft đưa vào sử dụng từ .Net Framework 3.0 trở đi, trong đó giao diện chương trình thiết kế bằng WPF được định nghĩa thông qua file XAML). Một file *.xaml về bản chất không cần phải được biên dịch, mà bản thân nó có thể chạy được trên bất kì trình duyệt nào ở bất kì máy tính Windows nào có cài đặt .Net 3.0 trở lên. Chẳng hạn như, với file a.xaml sau đây thể hiện 1 button có chữ Helloworld: <Button xmlns="" Margin="36" Foreground="Blue" FontSize="36pt">Hello, World! Dùng trình duyệt mở File a.xaml sẽ hiển thị kết quả như sau: Hình 4. HelloWorld Sự lưu trú của WF trên ứng dụng: WF không phải là ứng dụng chạy độc lập nên nó cần được lưu trú trong một ứng dụng chủ (host application).NET nào đó như Winform, ASP.NET, Console, Web Service… Với đặc tính này, WF chỉ cần tập trung vào xử lý các nghiệp vụ, những phần còn lại được giao cho ứng dụng chủ xử lý. Để tương tác với ứng dụng chủ WF cung cấp cơ chế cho phép truyền tải dữ liệu vào ra từ LCV cùng với các phương thức để điều khiển sự kiện nhằm tương tác với bên ngoài. Dưới đây là danh sách một số dịch vụ quan trọng nhằm phục vụ cho sự lưu trú cũng như thực thi LCV trong ứng dụng chủ: Persistence : Là cơ chế cho phép lưu trữ LCV xuống bộ nhớ một cách bền bỉ và khôi phục lại bất cứ khi nào. Nhờ cơ chế này, các LCV có thể được thực thi trong một khoảng thời gian dài (nhiều ngày, nhiều tháng…) đồng thời làm giảm gánh nặng cho hệ thống phần cứng khi có nhiều LCV cùng lưu trú trong các ứng dụng. Window WorkFlow Foudation 4.0 Tổng quan: Như các bạn đã biết, xây dựng nên một ứng dụng có thể là một thách thức, và chúng ta không ngừng tìm kiếm các công cụ và các framework để đơn giản hóa quá trình và giúp chúng ta tập trung giải quyết những thách thức thuộc về nghiệp vụ (bussiness). Chúng ta đã chuyển từ viết mã bằng ngôn ngữ máy như ngôn ngữ assambler đến ngôn ngữ cấp cao hơn như C # và Visual Basic, bởi vì nó dễ dàng cho sự phát triển ứng dụng của mình, nó đã loại bỏ các mối quan tâm ở cấp thấp như quản lý bộ nhớ và tăng hiệu suất của chương trình. Việc di chuyển đến. NET cho phép Common Language Runtime (CLR) để cấp phát bộ nhớ, dọn dẹp những đối tượng không cần thiết và loại bỏ xử lý cấp thấp như con trỏ.  Phần lớn sự phức tạp của một ứng dụng thể hiện trong logic và quá trình xử lý phía sau ứng dụng. Các vấn đề như thực hiện không đồng bộ hoặc song song và phối hợp các task để đáp ứng các yêu cầu người sử dụng hoặc yêu cầu dịch vụ một cách nhanh chóng, làm cho các nhà phát triển ứng dụng phải quay trở lại việc viết mã ở cấp thấp. Chúng ta cần một mô hình lập trình khai báo (a declarative programming model) mạnh mẽ và linh hoạt giống như chúng ta đã có trong giao diện người dùng trong Windows Presentation Foundation (WPF). Windows Workflow Foundation (WF) cung cấp một framework cho việc xây dựng ứng dụng và cung cấp cho ta một ngôn ngữ cấp cao hơn để xử lý các task không đồng bộ, song song và xử lý các task phức tạp khác. Có một runtime để quản lý bộ nhớ và các đối tượng, đã giúp chúng ta tập trung nhiều hơn vào các khía cạnh nghiệp vụ quan trọng. Tương tự như vậy, có một runtime có thể quản lý tính phức tạp của công việc không đồng bộ, nó cung cấp một bộ các tính năng cải thiện hiệu suất phát triển. WF là một bộ công cụ cho việc khai báo công việc, các activity giúp xác định logic công việc và kiểm soát luồng công việc, và runtime để thực thi các ứng dụng. Một cách ngắn gọn, WF sử dụng một ngôn ngữ cấp cao hơn để viết các ứng dụng, với mục tiêu làm cho các nhà phát triển phần mềm làm việc tốt hơn, các ứng dụng dễ dàng hơn để quản lý, và dễ dàng thay đổi hơn. Runtime WF không chỉ thực hiện các luồng công việc cho mình, nó cũng cung cấp các dịch vụ và tính năng quan trọng khi viết ứng dụng logic như bảo toàn trạng thái (persistence of state), đánh dấu trạng thái (bookmarking), tất cả đều dẫn đến luồng (thread) và xử lý linh hoạt cho phép mở rộng quy mô của quy trình nghiệp vụ.  Những điểm khác biệt so với WF 3.5: WF 4.0 khác hoàn toàn so với các phiên bản trước đó. Những ứng dụng WorkFlow trước đó chỉ có thể chạy được với .NET framework dưới 4.0. WF 4.0 được thiết kế lại mới hoàn toàn: những activity và service trong WF 4.0 không thể thay thế được với các phiên bản trước đó. -Trong WF 3.5 có cả code class và designer class: Code class chứa đựng bản cài đặt cho những đối tượng CodeActivity. Nó cũng chứa đựng định nghĩa thành viên lớp và bộ thụ lý sự kiện. Trong WF 4.0 không có code class trong phiên bản này. Bù lại WF 4.0 cung cấp những activity được xây dựng sẵn như WriteLine, Assign...Nếu những activity xây dựng sẵn này không đủ thì ta có thể tạo các custom activity bằng cách sử dụng CodeActivity. -Một điểm khác nữa là việc sử dụng variable và argument rõ ràng hơn. Bởi vì không có code file nên bạn không thể thêm các biến thành viên vào theo cách bình thường mình làm. Thay vào đó bạn phải định nghĩa nó theo cách của Workflow. -Cuối cùng ta xem lại file Program.cs là không có lớp WorkflowRuntime. Ở phiên bản trước ta phải tạo lớp WorkflowRuntime và gọi phương thức CreateWorkflow của nó. Trong WF 4.0 ta chỉ đơn giản gọi: WorkflowInvoker.Invoke(new Workflow1()) -Không còn workflow state machine trong phiên bản này. Những điểm mới trong WF4 Trong phiên bản 4 của Microsoft ® NET Framework, Windows Workflow Foundation giới thiệu một số lượng đáng kể của sự thay đổi so với phiên bản trước đó như NET 3.0 và 3.5. Trong thực tế, người ta đã xem xét lại phần cốt lõi của mô hình lập trình, runtime và công cụ và đã thiết kế lại tất cả những cái đó để tăng hiệu suất và năng suất so với các phiên bản trước đó. Những thay đổi quan trọng là cần thiết để cung cấp công cụ tốt nhất cho các developer áp dụng WF và cho phép WF tiếp tục là một thành phần nền tảng mạnh mẽ mà ta có thể xây dựng trong các ứng dụng của mình.  Trong WF3, dòng chảy của dữ liệu trong luồng công việc không rõ ràng. WF4 cung cấp một mô hình rõ ràng, chính xác cho luồng dữ liệu và tầm vực sử dụng của các đối số (argument) và các biến. Những khái niệm này quen thuộc làm đơn giản hóa cả định nghĩa về lưu trữ dữ liệu, cũng như dòng chảy của dữ liệu vào và ra của workflow. Mô hình luồng dữ liệu cũng làm cho các đầu vào dự kiến ​​và kết quả đầu ra của một activity rõ ràng hơn, cải thiện hiệu suất vào lúc runtime. Bắt đầu với WF4: Ứng dụng workflow đơn giản đầu tiên với WF4 Tạo một project Workflow Console Application trong Visual Studio 2010 với tên là TheFirstSimpleWorkf low Project mới sẽ bao gồm các file là Program.cs là tập tin chứa code C# (hoặc VB), Workflow1.xaml là file dùng để định nghĩa các activity trong workflow. Nếu đã từng làm việc với Windows Presentation Foundation thì các file XAML trở nên rất quen thuộc, đây là một dạng cấu trúc giống với XML cho phép người dùng có thể khai báo các activity trong một workflow. Visual Studio 2010 hỗ trợ giao diện đồ họa trực quan cho phép người dùng có thể tùy chỉnh các activity và các workflow. Khi làm việc với WF4, có một điểm đáng chú ý trong IDE là các control là Variables, Arguments và Imports. Đây là một trong những cải tiến đáng kể trong WF4. Có thể hiểu Variables trong WF4 một cách đơn giản như sau, nếu xem workflow là một class, thì Variables là class members được dùng để lưu trữ các data của workflow, hoặc các data sẽ được chia sẽ giữa các activity trong workflow. Các variable có thể được quy định mức độ như tồn tại trong toàn bộ workflow hoặc chỉ tồn tại trong một thành phần nhỏ hơn. Arguments cũng tương tự như Variables nhưng arguments được dùng để trao đổi dữ liệu ra hoặc vào trong workflow. Có thể xem arguments như các method parameters. Có một điểm chú ý là đối với arguments, chúng ta phải quy định Direction là In hay Out đồng nghĩa với quy định rằng argument dùng để truyền dữ liệu vào workflow hay truyền dữ liệu từ workflow ra ngoài. Xây dựng Workflow Để xây dựng workflow, ta có thể kéo thả các activity đã được xây dựng trong Toolbox vào designer. Trong ví dụ này, workflow sẽ chỉ xuất ra màn hình dòng “Hello, world”. Để thực hiện, kéo thả  một Sequence activity vào vùng designer và sau đó tiếp tục kéo thả WriteLine activity vào Sequence activity vừa mới tạo ra ở trước. Kết quả thu được là sơ đồ sau Tuy nhiên, nếu chú ý những gì chúng ta đang làm thì khi chạy ứng dụng này, chúng ta sẽ không thấy được kết quả. Do đó, để thấy được kết quả như thế nào, cần thêm vào một số dòng lệnh bằng các thêm vào ở tập tin Program.cs như sau namespace TheFirstSimpleWorkflow {     class Program     {         static void Main(string[] args)         {             WorkflowInvoker.Invoke(new Workflow1());             Console.WriteLine("Press Enter to exit");             Console.ReadLine();         }     } } Sau khi đã thực hiện các bước trên, kết quả thu được khi chạy ứng dụng như sau: Workflow được thể hiện trong XAML như thế nào? Để có thể hiểu rõ hơn đằng sau những gì mà chúng ta có thể thấy khi xây dựng một workflow bằng designer được cung cấp bởi Visual Studio 2010, hãy xem qua file Workflow1.xaml. Như chúng ta thấy, tất cả những gì chúng ta làm ở designer đều được thể hiện đằng sau bằng XAML. Làm việc với các Activity được xây dựng sẵn WF4.0 cung cấp cho người dùng rất nhiều các activity được xây dựng sẵn nhằm hỗ trợ tối đa cho việc xây dựng các ứng dựng workflow. Các activity xây dựng sẵn tiêu biểu có thể kể đến như If, While, Assign, Pick, Switch … Bên cạnh những activity cơ bản như trên, WF4.0 còn cung cấp rất nhiều các activity cao cấp hơn hỗ trợ việc xử lý message, tính toán song song như Send, Receive, RecieveAndSendReply, Paralell, …. Ví dụ mô phỏng một đồng hồ gõ chuông sau đây sẽ giúp chúng ta làm việc với các activity có sẵn. Quay trở lại với project TheFirstSimpleWorkflow Trong WF4.0, để lưu trữ data cần thiết trong workflow, chúng ta cần định nghĩa các variables để lưu trữ các data đó. Trong ví dụ này, chúng ta cần tạo ra 2 variables, một được dùng để xác định số tiếng chuông tương ứng với thời gian tương ứng, một được dùng để ghi nhớ rằng đã có bao nhiêu tiếng chuông đã được gõ. Để tạo một variable, có thể sử dụng control Variable và điền các thông tin cần thiết vào như hình dưới: Ngoài việc sử dụng control Variables như trên, để tùy chỉnh một variable, chúng ta vẫn có thể sử dụng Properties để tùy chỉnh các thông tin cho variable đó. Ở đây, chúng ta tạo ra 2 variable là counter và numberBells. Đối với counter thì giá trị mặc định ban đầu cho variable là 1, tuy nhiên đối với numberBells thì giá trị mặc định của variable này phụ thuộc vào thời gian, có nghĩa là chúng ta cần quy định giá trị này theo thời điểm mà nó chạy. Chọn vào variable numberBells, sau đó click vào button “…” của Default trong Properties windows để mở hộp thoại Expression Editor. Và kết quả thu được sau khi đã tạo ra 2 variables trên như sau: If Activity Giá trị của numberBells variable sẽ là giá trị của Hour của thời điểm hiện tại, tuy nhiên, Hour lại đưa về kiểu giờ 24. Do đó, nếu numberBells có giá trị lớn hơn 12, tức những giờ ở PM thì cần chuyển về lại những số nhỏ hơn 12. Để kiểm tra điều kiện này, chúng ta sử dụng If activity bằng cách kéo thả If activity từ toolbox vào sau WriteLine activity trong Sequence ban đầu, và Condition của If activity này sẽ là numberBells > 12. Assign activity Sau khi đã xác định Condition cho If activity ở trên. Nếu như numberBells thỏa condition ở trên thì cần phải thay đổi giá trị phù hợp cho numberBells. Để làm được việc này, WF4.0 cung cấp cho chúng ta một activity có tên là Assign dùng để thay đổi giá trị của variables trong workflow. Đối với Assign activity chúng ta cần quy định variable nào sẽ bị ảnh hưởng và giá trị thay đổi. While activity Để mô phỏng việc đổ chuông ứng với thời gian tương ứng, chúng ta sử dụng While activity. While activity bao gồm 2 phần là Condition và Body, giống với cấu trúc While thông thường mà chúng ta thường hay sử dụng. Số lần đổ chuông sẽ bằng với số giờ tương ứng, do đó, chúng ta cần quy định Condition cho While là counter <= numberBells Ở phần body, chúng ta sẽ thực  hiện việc mô phỏng các lần đổ chuông bằng việc xuất ra màn hình những dòng text đồng thời thực hiện việc cập nhật các thông tin như số lần đã đổ chuông … Sau khi hoàn thành tất cả các bước ở trên, chúng ta sẽ có được một workflow hoàn chỉnh như sau Kết quả thu được khi chạy ứng dụng workflow trên: Xây dựng workflow bằng code Ở mục 2, chúng ta đã tìm hiểu sơ lược về WF4.0 cùng cách sử dụng một số activity được xây dựng sẵn trong WF4.0. Việc xây dựng một workflow có thể được thực hiện thông qua việc sử dụng workflow designer mà Visual Studio 2010 hỗ trợ cho chúng ta. Bên cạnh đó, ngoài việc sử dụng workflow designer, chúng ta hoàn toàn có thể xây dựng một workflow hoàn toàn giống bằng việc sử dụng code C# hoặc VB.NET. Trong phần này, chúng ta sẽ thực hiện lại ví dụ xây dựng ứng dụng workflow đơn giản ở phần trước nhưng được thực hiện hoàn toàn bằng code C#. Sơ đồ workflow: Xây dựng ứng dụng workflow bằng code C# Tạo mới một project Console Application trong C#. Để có thể làm việc với activities trong WF4, chúng ta cần add references namespace System.Activities. Namespaces System.Activities cho phép người dùng có thể sử dụng các class liên quan đến WF như các activities, … Sau khi đã add references namespace System.Activities, thay đổi các dòng using trong file Program.cs thành như sau: using System; using System.Activities; using System.Activities.Statements; using System.Activities.Expressions; Đến đây, chúng ta thể bắt tay vào việc xây dựng workflow bằng code C#. static Activity CreateCodedWorkflow() {     return new Sequence()     {     }; } Để ý rằng, nhìn vào sơ đồ workflow của chúng ta, workflow sẽ có 1 Sequence chứa bên trong nhiều activities khác nhau, do đó hàm khởi tạo workflow của chúng ta cơ bản sẽ như sau: Khai báo variables cho workflow. Trong workflow ban đầu, chúng ta có 2 variable là counter và numberBells, để thực hiện khai báo 2 variable này bằng code C#, chúng ta làm như sau Variable counter = new Variable() {     Name = "counter",     Default = 1 }; Variable numberBells = new Variable() {     Name = "numberBells",     Default = DateTime.Now.Hour }; Tiếp tục định nghĩa các activities chứa trong Sequence chính của workflow return new Sequence() {     Variables = { counter, numberBells },     Activities =     {         // WriteLine activity         // Write "Hello, world" in a single line to console         new WriteLine()         {             Text = "Hello, world"         },         // If activity         // Becasuse DateTime.Now.Hour return in 24-based time         // so we have to convert to 12-based time         new If()         {             Condition = ExpressionServices.Convert                             (e => numberBells.Get(e) > 12),             Then = new Assign()             {                 Value = new InArgument(e => numberBells.Get(e) - 12),                 To = new OutArgument(numberBells)             }         },         // While activity         // Doing "bell"         new While()         {             Condition = ExpressionServices.Convert                         (e => counter.Get(e) <= numberBells.Get(e)),             Body = new Sequence()             {                 Activities =                 {                     // WriteLine activity                     // Write value of counter to console                     new WriteLine()                     {                         Text = new InArgument(e => "Sound bell: " + counter.Get(e).ToString())                     },                     // Assign activity                     // Update counter                     new Assign()                     {                             Value = new InArgument(e => counter.Get(e) + 1),                             To = new OutArgument(counter)                     },                     // Delay activity                     new Delay()                     {                         Duration = new TimeSpan(0,0,1)                     }}}}} }; Expression Khi định nghĩa các activities ở trên, chúng ta thấy rằng class ExpressionServices cung cấp cho ta method Convert cho phép tạo ra các đối tượng thuộc class InArgument. Việc sử dụng kiểu generic cho phép chúng ta có thể sử dụng method này với tất cả mọi kiểu dữ liệu. Các expression được biểu diễn bằng lamda expression ( biểu thức =>). Các parameters bên trái biểu thức => có thể được xem như là input, bản thân định nghĩa của expression chính là phần phía bên phải của biểu thức =>. Variables Một chú ý trong workflow, bản thân workflow không lưu trữ bất kỳ giá trị data nào thông qua các variables. Bản thân các variables chỉ là các định nghĩa của data được lưu trữ. Để có thể lấy ra được giá trị thật sự của các variables đó, chúng ta sử dụng phương thức Get(). Xây dựng Flowchart workflow: Trong mục này, chúng ta sẽ tìm hiểu về một activity rất quan trọng trong workflow, đó là Flowchart activity. Trong flowchart activity, các child activity được kết nối với nhau qua các cây quyết định (decision tree). Nếu như trong Sequence, các child activities được thực hiện một cách tuần tự top-down theo một thứ tự nhất định, thì trong flowchart activity, các child activities có thể được thực hiện theo một thứ tự bất kỳ và tùy thuộc vào các điều kiện tại các nhánh quyết định (decision branches). Tạo mới một project Console Workflow Application với tên là FlowcharWorkflow. Để bắt đầu xây dựng một flowchart, kéo thả một Flowchart activity từ toolbox vào workflow mới vừa tạo ra. Sau khi kéo thả thành công Flowchart activity vào workflow, thì kết quả thu được sẽ như sau Một Flowchart activity luôn có một node khởi đầu như trong diagram biểu diễn ở trên. Điểm khác biệt giữa Flowchart và Sequence chính là cách mà các child activities được sắp xếp. Trong Sequence, child activities được sắp xếp theo một thứ tự duy nhất là trên xuống dưới và đó cũng là thứ tự thực hiện của các activities, đồng thời sự liên kết giữa các activities trong Sequence được tạo ra tự động và theo một chiều nhất định là top-down. Trong Flowchart activity, child activities có thể được sắp xếp tùy ý và bắt buộc người dùng phải định nghĩa các mối liên kết giữa các activities. Tiếp tục thêm vào một WriteLine activity để xuất ra Console dòng chữ “Hello, Flowchart.”. Sau khi đã thêm vào WriteLine activity vào Flowchart, chúng ta phải thiết lập connections cho các activities trong flowchart này . Nếu chạy Flowchart vừa tạo ra ở trên thì chúng ta sẽ thu được trên màn hình Console một dòng là “Hello, Flowchart.”. Flowchart trên chỉ bao gồm 1 activity duy nhất cùng 1 flow duy nhất. Tuy nhiên, khi làm việc với Flowchart thì chúng ta sẽ có rất nhiều flow cùng với các điều kiện tương ứng cho mỗi flow. Để có thể xây dựng một flowchart như thế, WF4.0 cung cấp sẵn cho chúng ta các activities như là FlowDecision, FlowSwitch. FlowDecision activtity Quay trở lại với ví dụ trên, chúng ta sẽ sử dụng FlowDecision để đưa ra các lời chào thời gian khác nhau tùy thuộc vào thời gian hiện tại như là “Good morning”, “Good afternoon”, “Good evening”. Đối với FlowDecision, activity này sẽ dựa vào kết quả true hoặc false của condition mà quyết định hướng đi tiếp theo. Chúng ta có thể thấy rằng cách thực hiện này rất giống với If khi chỉ phụ thuộc vào 2 giá trị là true hoặc false để đưa ra quyết định. Để mở rộng khả năng của Flowchart, chúng ta có thể sử dụng một activity được xem là mở rộng của FlowDecision là FlowSwitch FlowSwitch activity FlowSwitch hoạt động giống với FlowDecision activity, tuy nhiên điểm khác biệt là FlowSwitch không phụ thuộc vào chỉ 2 giá trị true hoặc false mà FlowSwitch chấp nhận nhiều giá trị khác nhau. FlowSwitch giống với việc sử dụng switch trong C# thông thường. Có một điểm cần lưu ý là đối với FlowSwitch, vì là một generic class FlowSwitch nên khi kéo thả activity này từ toolbox thì Visual Studio 2010 đòi hỏi chúng ta phải tùy chọn kiểu T cho activity này. Sơ đồ FlowChart hoàn chỉnh: Arguments : Trong các mục trước, chúng ta đã được giới thiệu về Variables, Arguments trong WF4 và cũng như đã tìm hiểu cách để khai báo và làm việc với Variables và Arguments thông qua các ví dụ đơn giản. Nếu như Variables trong WF4 có thể được xem là các class members thì đối với Arguments có thể được xem như là các method properties. Trong phần này, chúng ta sẽ tìm hiểu cách khai báo và làm việc với Arguments trong một workflow. Bên cạnh đó là một số kỹ thuật đưa arguments vào workflow bằng code C#, khởi động workflow và nhận về kết quả từ workflow. Tạo workflow project mới Trong phần này, thông qua ví dụ xây dựng một workflow dùng để tính tổng giá trị của một đơn hàng chúng ta sẽ tìm hiểu về cách khai báo, làm việc cũng như một số kỹ thuật khác với Arguments. Tạo mới một project Workflow Console Application có tên là TotalAmountOfOrder. Sau khi khởi tạo project mới thành công, chúng ta sẽ định nghĩa các class tương ứng cần thiết cho ứng dụng. Trong ứng dụng ví dụ, chúng ta sẽ định nghĩa các class bao gồm Order và OrderItem như sau Định nghĩa Arguments cho workflow Thêm vào project một workflow mới có tên là TotalAmountWF. Sau đó bấm vào button Argument trong workflow designer để bắt đầu định nghĩa Arguments cho workflow. Workflow của chúng ta sẽ cần 2 argument là OrderInfo (InArgument – dùng để đưa thông tin về Order vào workflow) và TotalAmount (OutArgument – dùng để trả giá trị tính được ra ngoài). Bắt đầu xây dựng activities cho workflow bằng việc đưa vào một Sequence activity. Trong Sequence sẽ là một WriteLine activity xuất ra console “Order Received.” Để ý thấy rằng khi định nghĩa argument TotalAmount thì ở trường Default value chúng ta sẽ nhận được một thông báo là “Default value not supported”. Do đó, bước đầu tiên trong quá trình tính toán là gán giá trị ban đầu cho argument TotalAmount là 0 bằng việc thêm vào một Assign activity. Tiếp đến, sau khi đã khởi tạo giá trị ban đầu cho argument TotalAmount, chúng ta sẽ tiến hành tính giá trị của các Item có trong Order. Để thực hiện được việc này, WF4 đã cung cấp sẵn cho chúng ta một activity là ForEach, cho phép chúng ta duyệt lần lượt qua tất cả các phần tử trong một tập hợp. Chú ý rằng ForEach là một generic type, do đó cần phải quy định TypeArgument cho activity này, trong trường hợp này, TypeArgument cho ForEach activity là OrderItem. Với danh sách các Item có trong Order, chúng ta sẽ thực hiện việc tính tổng của các Item này theo công thức TotalAmount = TotalAmount + item.Price*item.Quantity Tiếp tục là tùy vào phương thức vận chuyển sẽ có giá thích hợp. Trong ví dụ, giả sử chúng ta có 3 phương thức là : mặc định – vận chuyển trong 1 tuần, vận chuyển trong 1 ngày, vận chuyển trong 2 ngày. Với yêu cầu này, chúng ta sẽ sử dụng Switch activity như sau Đến đây, ứng với mỗi trường hợp, chúng ta sẽ thực hiện activities tương ứng. Tuy nhiên, trong trường hợp này ngoài việc chúng ta có thể sử dụng Assign activity để cập nhật lại TotalAmount, chúng ta sẽ tìm hiểu một số activity khác được cung cấp trong namespace System.Activities.Expressions. Một số activities trong namespace System.Activities.Expressions WF4 còn cung cấp cho chúng ta một số các activities khác trong namespace System.Activities.Expressions. Các activities được cung cấp tiêu biểu như Add, Subtract, Multiply, Divide, Equals, AndAlso, OrElse, …. Tuy nhiên, để có thể sử dụng các activities này, chúng ta phải đưa vào toolbox bằng tay để sử dụng trong designer hoặc cần khai báo using nếu chúng ta muốn sử dụng trong code. Sau khi đã thực hiện việc đưa các activities này ra toolbox cho thuận tiện trong việc sử dụng thì chúng ta có thể thoải mái kéo thả các activities này vào trong workflow. Đây là một ví dụ trong việc sử dụng Add activities. Cứ tiếp tục với các case còn lại và thực hiện tiếp với việc đưa coupon vào bằng các activities chúng ta sẽ được một workflow hoàn chỉnh như sau Đưa Arguments vào workflow và chạy workflow Workflow trên sau khi đã được định nghĩa, để có thể thực thi được thì cần truyền vào OrderInfo thông qua Arguments. var inArguments = new Dictionary(); inArguments.Add("OrderInfo", myOrder); var outArguments = WorkflowInvoker.Invoke(new TotalAmountWF(), inArguments); var totalAmount = (decimal)outArguments["TotalAmount"]; Console.WriteLine("Workflow returns ${0} for total amount.", totalAmount); Đoạn mã sau sẽ thực hiện việc khai báo các in-arguments cho workflow, thực thi workflow và sau đó là nhận về out-arguments từ workflow sau khi đã thực thi xong Xây dựng custom activity: Bên cạnh việc sử dụng các activity có sẵn trong WF4, chúng ta có thể xây dựng thêm các custom activity tương ứng với các yêu cầu đặc biệt. Kế thừa từ Activity Để xây dựng một custom activity, chúng ta có thể kế thừa từ class Activity. Ở đây chúng ta sẽ xây dựng một custom activity là AppendString thực hiện việc kết nối 2 chuỗi lại với nhau. public sealed class AppendString : Activity {     public AppendString()     {     } } AppendString activity cần đưa vào 2 string để thực hiện việc ghép nối và trả về string đã ghép nối. Để thực hiện cho phép đưa vào custom activity, chúng ta cần 2 InArgument và 2 argument này là bắt buộc. public sealed class AppendString : Activity {     [RequiredArgument]     public InArgument TheFirstStr { get; set; }     [RequiredArgument]     public InArgument TheSecondStr { get; set; }     public AppendString()     {     } } Đối với các custom activities thừa kế từ Activity, để định nghĩa phần logic code của activity, chúng ta sẽ thông qua property Implementation, thông qua property này, chúng ta sẽ định nghĩa 1 delegate để thực hiện logic code cho activity. public AppendString() {     // Define the implementation for AppendString activity                 this.Implementation = () => new Assign()     {         Value = new InArgument(context => TheFirstStr.Get(context)                                         + TheSecondStr.Get(context)),         To = new OutArgument(context => this.Result.Get(context))     }; } Sau khi đã định nghĩa xong custom activity AppendString, chúng ta tiến hành kiểm tra kết quả  thu được thông qua method sau: static void AppendStringDemo() {     // Initialize AppendString activity     AppendString appendString = new AppendString()     {         TheFirstStr = "Hello ",         TheSecondStr = "custom activiy in WF4." };     // Using WorkflowInvorker to invoke appendString activity     // appendString is a generic-activity Activity,     // so Invoke method will return a string     var outArgument = WorkflowInvoker.Invoke(appendString);     Console.WriteLine("Result: {0}", outArgument);     Console.WriteLine("Press Enter to exit ...");     Console.ReadLine(); } Và kết quả thu được như sau: Chú ý: Đối với phương thức Invoke trong class WorkflowInvoker, nếu chúng ta invoke 1 activity được thừa kế từ Activity thì kết quả trả về từ phương thức WorkflowInvoker.Invoke sẽ có cùng kiểu dữ liệu là TResult mà chúng ta thừa kế từ Activity. Chú ý: Như trong những phần trước đã nhắc đến, để có thể lấy được giá trị hay dữ liệu của các Arguments, chúng ta phải thông qua phương thức Get và Workflow context. Tuy nhiên, với việc sử dụng lamda expression thì công việc này trở nên rất đơn giản. Cụ thể trong ví dụ trên, để có thể lấy ra dữ liệu của TheFirstStr chúng ta sử dụng expression là context => TheFirstStr.Get(context). Kế thừa từ CodeActivity Để xây dựng một custom activity, ngoài cách kế thừa từ lớp Activity, chúng ta còn có thể kế thừa từ lớp CodeActivity. Mặc dù, kết quả thu được giống nhau nhưng vẫn tồn tại sự khác biệt giữa 2 cách thực hiện này. Vì CodeActivity là một abstract class, do đó khi thừa kế từ class này, chúng ta phải implement cho các abstract member từ class CodeActivity. Cụ thể nhất là để custom activity có thể thực thi được, chúng ta phải implement method Excute() public sealed class AnotherAppendString : CodeActivity {     protected override string Execute(CodeActivityContext context)     {         throw new System.NotImplementedException();     } } Một điểm khác biệt nữa là nếu như kế thừa từ Activity chúng ta phải khai báo Func cho property Implementation thì đối với cách thực này, chúng ta sẽ định nghĩa logic code của activity trong thân method Excute như sau: public sealed class AnotherAppendString : CodeActivity {     [RequiredArgument]     public InArgument TheFirstStr { get; set; }     [RequiredArgument]     public InArgument TheSecondStr { get; set; }     protected override string Execute(CodeActivityContext context)     {         return context.GetValue(TheFirstStr)                 + context.GetValue(TheSecondStr);     } } Và kết quả thu được sẽ giống với kết quả thu được khi thực hiện xây dựng custom activity bằng cách kế thừa từ Activity.

Các file đính kèm theo tài liệu này:

  • docTìm hiểu mô hình và công nghệ wf 40.doc