Tag Archives: aktivite

Workflow Foundation ile Kopyalanarak Çoğaltılan Aktiviteler

Bir önceki yazımızda sırasıyla geçiş yaptığımız argümanlara göre toplam maliyeti hesaplayan bir workflow oluşturmuştuk. Şimdiye kadar sadece taşıma ücretini hesaplamıştık. Şimdi bu yazımızda her bir ürünün lojik olarak maliyetlerini ekleyeceğiz.

Bu yüzden bir önceki yazımızda oluşturduğumuz Siparisİslemi projeminiz üzerinde çalışacağız. Visual Studio’yu başlatıp yeni bir proje oluşturalım. Other Project Types –> Visual Studio Solutions seçeneği ile Kopyalanarak Çoğaltılan Aktiviteler adında yeni bir boş solution oluşturalım. Şimdi de C:\Users\Soner\Documents\Visual Studio 2010\Projects\Siparisİslemi altındaki Siparisİslemi klasörünü az önce oluşturduğumuz Kopyalanarak Çoğaltılan Aktiviteler klasörünün içine kopyalayalım.

WF-Folder

Solution Explorer kısmından Add->Existing Project diyerek Kopyalanarak Çoğaltılan Aktiviteler/Siparisİslem klasörünün içinde bulunan Siparisİslemi.csproj dosyamızı ekleyelim.

SiparişÜrün İşlemini Ekleyelim

ForEach aktivitesi Collection kısmındaki her bir madde için bir aktivite çalıştırır. Bu proje için bizim tam da istediğimiz budur aslında.

SiparisWF.xaml dosyamızı dizayn modunda açalım.  “İlk Toplam” aktivitemizin altına bir adet ForEach<T> aktivitesi sürükleyip bırakalım. DisplayName özelliğini Sipariş Ürünlerini Biriktirme olarak adlandıralım. Expression özelliğine SiparisBilgisi.Ogeler yazalım. Fakat bunu yazdığımızda bir hata alırız. Aktivitenin <T> olarak tanımlanması bu aktivitenin generic sınıf olduğunu, bu yüzden tip olarak collection içeren bir tip tanımlamamız gerektiğini bize gösterir. Varsayılan tip olarak Int32 seçildiğinden SiparisBilgisi.Ogeler ifadesi de bir Int32 tipinde collection içermediğinden bu hatayı alırız. Bu yüzden ArgumentType seçeneğini Browse Type diyerek Siparisİslemi.SiparisOge olarak belirtmeliyiz.

WF-BrowseType2

Bu tipi seçtiğimizde artık SiparisBilgisi.Ogeler değeri Siparisİslemi.SiparisOge tipinde bir collection içerir. (Siparis.cs içerisinde yazdığımız kod nedeniyle) Hata ortadan kalkmış olur. Şimdi ForEach<T> aktivitesi içerisine bir Assign aktivitesi sürükleyip bırakalım.

NOT: Foreach<T> aktivitesi içerisine sadece bir basit aktivite sürükleyebiliriz. Eğer birden fazla aktiviteye ihtiyacınız olursa, içerisine bir Sequence aktivitesi sürükleyip diğer aktiviteleri bunun içerisine yerleştirebilirsiniz.

Assign aktivitemizin To özelliğini ToplamMaliyet, Value özelliğini de ToplamMaliyet + (item.Miktar * 10.0D) olarak atayalım. Bu işlem sipariş içerisindeki her miktar için toplam maliyete 10 ekler.

Şimdi “Sipariş Ürünlerini Biriktirme” aktivitesinin altına bir Writeline aktivitesi ekleyelim. DisplayName özelliğine “Toplam Maliyeti Göster”, Text özelliğine de “Ürün Toplamı: ” + ToplamMaliyet.ToString() ifadesini atayalım. Bu sipariş edilmiş ürünlerin toplamını, taşıma ücretini eklemeden önce gösterir.

Sipariş Ürünlerini Ekleme

Şimdi bu özelliği test etmeden önce Sipariş sınıfı içerisindeki SiparisOge nesnelerini düzenlememiz lazım. Program.cs dosyamızı açalım ve aşağıdaki kodumuzu siparisim nesnesini oluşturduktan hemen sonra yazmaya başlayalım.


siparisim.Ogeler.Add(new SiparisOge
{
SiparisOgeID = 1,
Miktar = 1,
OgeID = "12345",
Tanım = "Alet"
});

siparisim.Ogeler.Add(new SiparisOge
{
SiparisOgeID = 2,
Miktar = 3,
OgeID = "12346",
Tanım = "Küçük Alet"
});

siparisim.Ogeler.Add(new SiparisOge
{
SiparisOgeID = 3,
Miktar = 2,
OgeID = "12347",
Tanım = "Süper Alet"
});

Şimdi F5 ile projemizi çalıştıralım.

Sipariş Alındı
Ürün Toplamı: 60
Toplam Maliyet: 120,0
Workflow’un döndürdüğü Toplam Maliyet 120,0
Enter to Exit

Peki bu nasıl hesaplandı?

SiparisOge sınıfının miktar olarak sırasıyla 1, 3, 2 ogeler mevcut. Bunların toplamı 6 yapıyor. Her biri için 10 eklediğimizi hatırlayalım. Bu da toplamı 60 yapar. Bir önceki yazıda gördüğümüz üzere Taşıma Ücreti’de 60 olarak hesaplamıştık. Bu ikisinin toplamı da sonuçta gördüğümüz gibi 120 değerini elde ediyoruz.

Tüm Program.cs kodumuz aşağıdaki şekildedir;


using System;
 using System.Linq;
 using System.Activities;
 using System.Activities.Statements;
 using System.Collections.Generic;

namespace Siparisİslemi
 {

class Program
 {
 static void Main(string[] args)
 {
 Siparis siparisim = new Siparis
 {
 SiparisID = 1,
 Tanım = "Sipariş Tanımı",
 SiparisMetodu = "İkiSonrakiGün",
 ToplamAgirlik = 100,
 };

siparisim.Ogeler.Add(new SiparisOge
 {
 SiparisOgeID = 1,
 Miktar = 1,
 OgeID = "12345",
 Tanım = "Alet"
 });

siparisim.Ogeler.Add(new SiparisOge
 {
 SiparisOgeID = 2,
 Miktar = 3,
 OgeID = "12346",
 Tanım = "Küçük Alet"
 });

siparisim.Ogeler.Add(new SiparisOge
 {
 SiparisOgeID = 3,
 Miktar = 2,
 OgeID = "12347",
 Tanım = "Süper Alet"
 });

//Workflow için input argümanlarını oluşturalım
 IDictionary<string, object> input = new Dictionary<string, object>
 {
 {"SiparisBilgisi", siparisim}
 };

//Workflow'u çalıştıralım
 IDictionary<string, object> output = WorkflowInvoker.Invoke(new SiparisWF(), input);

//Workflow'dan geri dönen ToplamMaliyet'i alalım
 decimal toplam = (decimal)output["ToplamMaliyet"];
 Console.WriteLine("Workflow'un döndürdüğü Toplam Maliyet {0}", toplam);
 Console.WriteLine("Enter to Exit");
 Console.ReadLine();
 }
 }
 }

ParallelForEach Aktivitesi

ForEach aktivitesi yerine ParallelForEach aktiviteisi de kullanabilirdik. İki aktivite de aynı şekilde yapılandırılmıştır. Tek fark aktivitelerin nasıl çalıştırıldığıdır.

ParallelForEach’in adından da anlaşılacağı gibi alt aktiviteler eşzamanlı olarak çalışırlar. ForEach aktivitesinde ise alt aktiviteler sıralı olarak çalışırlar.

Workflow Foundation 4.0 ile Temel Elemanları Eklemek

Workflow Foundation 4.0, bize kullanmak için If, While, Assign, Sequence gibi yönetimsel elemanlar sunar. Bu yazıda bu elemanların nasıl kullanılacağına dair bilgiler vermeye çalışacağım.

WF 4.0 kullanıcıları workflow elemanları tarafından kullanılan tüm değişkenleri tanımlamak zorundadırlar. Şimdi projemize iki adet değişken tanımlayalım. Birinci değişkenimiz kaç adet zile ihtiyacımız olduğunu gösteren NumberOfBells, diğerini de şimdiye kadar kaç defa zil duyulduğunu gösteren Counter. Peki bu değişkenleri nasıl tanımlıyoruz?

Öncelikle projemize bir adet Sequence aktivitesi ekleyelim. Daha sonra bu aktivitenin üzerine bir defa tıklayıp tasarım kısmında sol altta bulunan “Variables” sekmesine tıklayalım. Daha sonra “Create Variable” kısmına tıklayıp ismi Counter olan tipi de Int32 olan bir değişken kaydedelim. Scope kısmını Sequence olarak bırakabilirsiniz. Bunun anlamı; o değişken Sequence ve onun soyundan gelen tüm aktiviteler tarafından kullanılabilir olmasıdır. Aynı şekilde tekrar “Create Variable” diyelim. Bu sefer değişkenimizi Properties penceresinden tanımlayalım. İsmi NumberOfBells ve tipi de Int32 olan bir değişken tanımlayalım. Scope kısmını yeniden Sequence olarak bırakalım.

WF-VariableDefinition

WF-Properties2

Daha sonra ifadeler yazabileceğimiz yukarıdaki resimde kırmızı kutu içerisinde gösterdiğim Expression Editor’ü açalım. Ve oraya DateAndTime.Now.Hour ifadesini yazalım.

WF-ExpressionEditor

Bu ifadeyi default propertie olarak kaydedelim. Bu işlem NumberOfBells değişkenini günün o andaki saat değerine atar. Bu işlemden sonra değişkenlerimiz aşağıdaki şekilde görünmelidir.

WF-Variables3

Şimdide IF kullanımına bakalım;

DateAndTime sınıfının Hour üyesi geriye 24 saatlik sistemde saati geri döndürür. Örneğin; saat öğleden sonra 3 ise geriye 15 değerini döndürür. Öncelikle diagramımızda bulunan Sequence yapısının içine Toolbox’ta bulunan Writeline aktivitesini sürükleyip bırakalım. Daha sonra bu aktivitenin DisplayName özelliğini Merhaba olarak değiştirelim. Tekrar Sequence içerisine bir If aktivitesi sürükleyip bırakalım.

NOT: Bu adımda If ve Sequence aktivitelerinin sağ üst köşelerinde kırmızı renkli hata kutuları çıkacaktır. If aktivitesindeki kutucuk If aktivitesi içerisinde henüz herhangi bir koşul (condition) yazılmadığını, Sequence aktivitesindeki kutucuk ise ya bu aktivitede ya da alt aktivitelerinde bir hata olduğunu gösterir. Bu hataları kutucukların üstüne gelerek görebilirsiniz.

WF-If

Şimdi If aktivitesini Properties kısmından DisplayName özelliğini “PM için ayarla” olarak değiştirelim. If aktivitesinin 3 kısmı vardır. Condition kısmı hangi koşulun hesaplanacağını gösterir. Bir Boolean (true ya da false) değer çözmelidir bu koşul. Eğer ifade True is Then aktivitesi, eğer ifade False ise Else aktivitesi çalıştırılır. Hem Then hem de Else aktivitelerinin ikisini birden tanımlamak zorunda değiliz. Eğer hiçbir aktivite tanımlanmasa, hiçbir aktivite çalıştırılmaz. Şimdi koşulumuza NumberOfBells>12 ifadesini girelim.

Şimdi de Assign aktivitesini Then kısmımızın içine sürükleyip bırakalım. Assign aktivitesi size bir değişkene ya da bir argümana bir değer atamanıza imkan verir. Hem To hem de Value özelliklerinin bir ifade içerebileceğine dikkat edin. To özelliğine NumberOfBells, Value özelliğine de NumberOfBells – 12 ifadelerini girelim.

WF-Properties2

WF 4.0’da bir çok aktivite compound aktivitedir yani başka aktiviteleri içerebilirler. If aktivitesi buna güzel bir örnek olarak gösterilebilir.

Sıra geldi While aktivitesini kullanmaya. While aktivitesini, ismi “PM için ayarla” olan If aktivitesinin altına sürükleyip bırakalım. Ardından DisplayName özelliğini “Zil Çalınma Sayısı” olarak değiştirelim.

WF-While

While aktivitesi, içerisinde yazılan ifade true olduğu sürece Body kısmındaki aktiviteleri çalıştırır. İlk önce koşul hesaplanır, eğer true ise, içindeki aktiviteler çalıştırılır. Bu durum, koşul false olana kadar devam eder.

NOT: İleride göreceğimiz DoWhile aktivitesi ile While aktivitesi arasındaki fark, programlama olduğu gibidir. DoWhile aktivitesinde önce içindeki aktiviteler bir kez çalıştırılır, sonra koşul çalıştırılıp true olup olmadığı kontrol edilir. While aktivitesinde ise, önce koşul çalıştırılır. Koşul true ise içindeki aktiviteler çalıştırılır. Eğer koşul false ise içindeki ifadeler hiçbir zaman çalıştırılmazlar.

While aktivitesinin koşul kısmına Counter <= NumberOfBells ifadesini yazalım. Daha sonra Body kısmına bir Sequence aktivitesini sürükleyip bırakalım. Bunun da DisplayName özelliğini “Zil Çalınma Sayısı” olarak değiştirelim.

WF-Sequence

Şimdi bu “Zil Çalınma Sayısı” isimli Sequence aktivitemizin içine bir Writeline aktivitesi sürükleyip bırakalım. Writeline aktivitesinin Text özelliğine de Counter.ToString() ifadesini yazalım. Bunun amacı kaç kere zil çaldığını konsola yazdırmaktır. Ardından bu Writeline aktivitesinin altına bir Assign aktivitesi yerleştirelim. To kısmına Counter, Value kısmına ise Counter + 1 yazalım. Bu kısaca Counter değişkenini bir arttıracaktır.

WF-Assign2

Ardından bu Assign aktivitesinin altına bir Delay aktivitesi sürükleyip bırakalım. Kısaca Delay aktivitesi, belirli bir zaman periyodu için o aktiviteyi durdurur. Delay aktivitesinin Duration adında tek bir özelliği vardır. Bu özellik aktivitenin ne kadar duracağını gösterir.  Bu özelliğe TimeSpan.FromSeconds(1) ifadesini yerleştirelim.

“Zil Çalınma Sayısı” adındaki While aktivitesini sağ üst köşesinden daraltalım.

WF-Collapse

Sonra da bu While aktivitesinin altına bir Writeline aktivitesi ekleyelim. DisplayName özelliğini “Zaman:” , Text özelliğini de “Şu anki zaman: ” + DateTime.Now.ToString() şeklinde yazalım.

“Zaman” aktivitesinin altına da bir If aktivitesini sürükleyelim ve ismini de “Selamlama” olarak koyalım. Koşul kısmına da DateTime.Now.Hour >= 18 ifadesini yerleştirelim. Şimdi de Selamlama aktivitesinin içindeki Then ve Else kısımlarına da birer Writeline aktivitesi yerleştirelim. Then kısmındaki aktivitenin Text özelliğine “İyi Akşamlar”, Else kısmındaki aktivitenin Text özelliğine de “İyi Günler” yazalım. Şimdi de projemizi kaydedip F5 ile çalıştıralım.

0
1
2
3
4
5
Şu anki zaman: 30.07.2012 17:00:16
İyi Günler
Press any key to continue . . .

 

Görüleceği üzere 0-5 arası her rakamı yazdırırken 1 saniye bekleme yaptı program. Bu durum Delay aktivitesi sayesinde gerçekleşir.

Bu yazıda Workflow Foundation içerisindeki, bizim de programlama dillerinden bildiğimiz ifadelerin aktivitelerini inceledik.