Bu site emekli olmuştur. Arşiv amaçlı olarak BT AKADEMİ sponsorluğunda yayın hayatına devam etmektedir.




C#nedir?com
 
YAZAR HAKKINDA
Erdem Özdemir
Erdem Özdemir
http://www.csharpnedir.com/
İletişme geçmek için tıklayın.
2 Makalesi yayınlanmakta.
Yazar hakkında detaylı bilgi için tıklayın.
Yayınlanan diğer makaleleri için tıklayın.
İlgili etiketler: condition evaluate faaliyet imyinterface isimli metodu myeventargs offerid private public return subscriber subscriber) tipinde workflow .NET 3.x Erdem Özdemir
 
YAZI HAKKINDA
Türü : Makale
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
Seviyesi : Orta
Kategori : .NET 3.x
Yayınlanma Tarihi : 19.4.2007
Okunma Sayısı : 24728
Yorum Sayısı : 3     yorum yaz
Site İçi AramaSİTE İÇİ ARAMA
Üye Girişini AçÜye GİRİŞİ
Üye girişi için tıklayın.
Kullanıcı Adı
Şifre
 
Beni her zaman hatırla
Bir hafta boyunca kullanıcı bilgilerinizi kullanıcı çıkışı yapana kadar hatırlar. (Paylaşılan bilgisayarlarda önerilmez.)
 
Şifremi / Kullanıcı Adımı unuttum.
 
.net TV RSS Serbest KÖŞE (?)
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
emre TAŞ
Silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
Makale Gönder Bende Yazmak İstiyorum
.net TV RSSBlogroll
Turhal Temizer
Conda install environment.yml Package 8.12.2024
Turhal Temizer
Mac OS/X Removing CUDA 8.12.2024
Burak Selim Şenyurt
Rust ile ECS Yaklaşımını Anlamak 8.12.2024
Burak Selim Şenyurt
Birlikte Rust Öğrenelim Serisi 8.12.2024
  Diğer Herşey
Sponsorlar
BT Akademi
Medya Portakal
Video Hosting Sponsoru
Csharpnedir.com bir Ineta üyesidir
Uzman Abi
Her Yönüyle C# - Sefer Algan
Windows Workflow Foundation Detay
 
Kapat
Sayfayı Yazdır Sık Kullanılanlara Ekle Arkadaşıma Gönder MySpace Del.Ico.Us Digg Facebook Google Mixx Reddit StumbleUpon
Bundan önceki makalemde sizlere Windows Workflow Foundation hakkında giriş bilgileri vermeye çalışmıştım. Bu makalemde ise WF’i gerçek hayatta kullanılabilcek bir örnek ile daha detaylı olarak anlatmaya çalışacağım. Örneğimizde belirli kurallara göre oy verme işlemi ve bunun sonucunda bir onaylama mekanizmasını işleyeceğiz. Oy verme işlemi bir adet form üzerinde olacak. Bu form üzerinde oy veren kişinin adını gireceği bir adet textbox, oyunun ağırlığını gireceği bir numeric UpDown, kabul edip etmediğine dair iki adet radioButton ve oy vermek için bir adet buton bulunmakta.


Butona tıkladıktan sonra iş akışımızda belirlediğimiz kurallar çerçevesinde çeşitli işlemler gerçekleşecek ve bize işlemin onaylanıp onaylanmadığını söyleyecek. Biz bütün oy verme işleminlerini bu form üzerinde yapacağız . Bütünüyle gerçek bir proje yapmak istersek girilen oyları bir veritabanında tutup aynı exe’ yi başka yerlerde de çalıştırabiliriz. Böylece oy verme işleminin farklı mekanlarda farklı kişiler tarafında yapılamasını sağlayabiliriz.

Formumuzda oy verecek kişinin bilgilerini tutmak için önce bir Subscriber sınıfı tasarlayıp bunu ayrı bir dll’de tutacağız ki hem formumuzda hem de iş akışı kütüphanemizde kullanabilelim.
using System;
namespace Common
{
    [Serializable] public class Subscriber
    {
         private Guid id;
         public Guid ID
         {
            get { return id; }
            set { id = value; }
         }
         private string name;
         public string Name
         {
             get { return name; }
             set { name = value; }
         }
         private double rateWeight;
         public double RateWeight
         {
              get { return rateWeight; }
              set { rateWeight = value; }
         }
         private bool accepted;
         public bool Accepted
         {
               get { return accepted; }
               set { accepted = value; }
         }
    }
}


Sınıfımızda dikkati çeken iki özellik var. Birincisi sınıfımıza Serializable attribute’ ünü ekledik ki iş akışında kullanabilelim. İkincisi ID property’ si Guid türünde, bununda nedeni her iş akışının bir Guid ‘ i olur. Biz de bunu oy veren kişinin ID ‘ si olarak kullandık.

Sıra artık iş akışımız için kullanacağımız ktüphaneyi oluşturmakta. MyActivityLibrary adını verdiğimiz projemize bir adet XOML uzantılı Sequential Workflow ekliyoruz. Ve MyWorkflowActivity.xoml olarak adlandırıyoruz. Formumuza bir adet listenActivity ekliyoruz. ListenaActivity olay tabanlı çalışan bir faaliyettir(Activity) yani dışarıdan bir olay gelmesini bekler. Bu nedenle her dalının ilk elemanı IEventActivity arayüzünü uygulayan bir faaliyet olmalıdır. Biz bu örneğimizde handleExternalEventActivity kullanıyoruz.aşağıdaki resimde de gördüğümüz gibi ilk dalın ilk elemanı bir handleExternalEventActivity olduğu için bir uyarı yok ama ikinci dalda böyle bir faaliyet olmadığı için uyarı veriyor.


İkinci dalın da ilk elemanına bir adet handleExternalEventActivity yerleştiriyoruz. Böylece listenActivity1 tasarımı tamam.Şimdi içinde ki faaliyetlerin özelliklerini tamamlayalım. offerRejected isimli handleExternalEventActivity ve rejectOffer isimli callExternalMethodActivity ‘inin özelliklerine bir göz attığımızda bizden arayüz geçerli bir arayüz tipi istediklerini görüyoruz. O zaman geçerli bir arayüz tasarlamamız gerekiyor.

Projemize rahat anlaşılması amacıyla Code isimli yeni bir klasör oluşturuyoruz. Ve yazacağımız sınıfları bu klasörde tutacağız.

using System;
using System.Workflow.Activities;
using Common;

namespace MyActivityLibrary.Code
{
    [ExternalDataExchange]
    interface IMyInterface
    {
        event EventHandler<MyEventArgs> OfferRejected;
        event EventHandler<MyEventArgs> OfferAccepted;

        void AcceptOffer(Guid offerID, Subscriber subscriber);
        void RejectOffer(Guid offerID, Subscriber subscriber);

        bool Evaluate();
    }
}
---IMyInterface.cs---

IMyInterface arayüzünde iki adet EventHandler var bunlar handleExternalEventActivity ‘ ler tarafından kullanılacaklar. EventHandler’ların Eventarg’ları ise bizim tarafımızdan tasarlanmış, hangi kullanıcının bu olayı tetiklediğini bilmemiz için kurucu metodunda Subscriber sınıfından bir parametre alan serilize edilebilen MyEventArgs isimli ExternalDataEventArgs sınıfından türemiş bir sınıftır. ExternalDataEventArgs sınıfı ise bir handleExternalEventActivity tarafından tetiklenen olayla ilgili bilgileri almamıza yarayan bir sınıftır.
using System;
using System.Workflow.Activities;
using Common;
namespace MyActivityLibrary.Code
{
    [Serializable]
    public class MyEventArgs : ExternalDataEventArgs
    {
        private Subscriber subscriber;
        public Subscriber Subscriber
        {
            get { return subscriber; }
            set { subscriber = value; }
        }
        public MyEventArgs(Guid guid, Subscriber subscriber) : base(guid)
        {
             this.subscriber = subscriber;
        }
    }
}
--- MyEventArgs .cs---


Üç adet de metod vardır :
AcceptOffer metodu acceptOffer callExternalMethodActivity,
RejectOffer metodu rejectOffer callExternalMethodActivity,
Evaluate metodu ise evaluate callExternalMethodActivity tarafından kullanılacaktır.

Bu metod ve olayları iş akışımızda bulunan faaliyelerin özelliklerine atadıktan sonra handleExternalEventActivity ‘lerin bir adet de “e” özelliğinin bulunduğunu görüyoruz. Bu faaliyet ile ilintili olay tetiklendiğinde, olayın EventArg’ına bağlancak değerdir. Biz bunun için kendi Eventarg’ımızı yazmıştık ve bu Eventarg Subscriber tipinde bir değişken alıyordu. Onun için offerAccepted faaliyetinde e ‘nin yanındaki tuşa bastığımızda çıkan ekranda “Bind to a new member ” seçeneğinden “Create Field” ‘i seçip bu yeni alanın oluşturulmasını ve bağlanmasını sağlıyoruz.



Bu yaptıklarımız karşımıza şöyle çıkmakta:
offerAcc değişkeni .cs dosyasında oluşturlmakta,
public MyEventArgs offerAcc = default(MyEventArgs);

faaliyete bağlanması ise XAML dosyasında yapılmaktadır.
<HandleExternalEventActivity x:Name="offerAccepted" EventName="OfferAccepted" InterfaceType="{x:Type MyActivityLibrary.Code.IMyInterface}">

 <HandleExternalEventActivity.ParameterBindings>

  <WorkflowParameterBinding ParameterName="e">

   <WorkflowParameterBinding.Value>

    <ActivityBind Name="MyWorkflowActivity" Path="offerAcc" />

   </WorkflowParameterBinding.Value>

  </WorkflowParameterBinding>

 </HandleExternalEventActivity.ParameterBindings>

</HandleExternalEventActivity> 

Yaptıklarımızın aynısını offerRejected içinde yapıyoruz.
handleExternalEventActivity ‘lerle yakaladığımız EventArg’ın Subscriber tipindeki özelliğine , Subscriber tipinde değer atamamız gerekir. Bunun için Subscriber tipinde bir özellik oluşturuyoruz. Peki atama işini nererde yapacağız. Bu işi de callExternalMethodActivity’lerin MethodInvoking olaylarına bağlarız. Böylelikle olayı tetikleyen kişinin özelliklerine MyWorkflowActivity içinde erişebileceğiz.

public partial class MyWorkflowActivity : SequentialWorkflowActivity
{
    public MyEventArgs offerAcc = default(MyEventArgs);
    public MyEventArgs offerRej = default(MyEventArgs);
    private Subscriber subscriber;
    public Subscriber Subscriber
    {
         get { return subscriber; }
         set { subscriber = value; }
    }
    private void acceptOffer_MethodInvoking(object sender, EventArgs e)
    {
         subscriber = offerAcc.Subscriber;
    }
    private void rejectOffer_MethodInvoking(object sender, EventArgs e)
    {
        subscriber = offerRej.Subscriber;
    }
}

acceptOffer ve rejectOffer aktivitelerini bağlayacağımız metodlar için tasarladığımız arayüzdeki ilgili metodlar iki adet parametre almaktaydılar; Guid offerID, Subscriber subscriber. Bunları da gerekli özelliklere bağlamamız gerekmektedir. Bunun için Subscriber tipinde bir özellik zaten var. Guid tipinde bit özellik daha tanımlarsak gerekli özelliklere sahip olmuş olacağız.

private Guid offerID;
public Guid OfferID
{
    get { return offerID; }
    set { offerID = value; }
}



Resimde görüldüğü gibi bağlamaları iki faaliyet içinde yapabiliriz.



Olayları yakaladık ve bunlarla ilgili çeşitli işlemler yaptıktan sonra sıra artık değerlendirme aşamasına geldi. Ama senaryomuzda değerlendirmenin olabilmesi için en az 10 tane oy gelmesi gereksin. Bunun için bir adet ifElseActivity kullanıyoruz. Bu faaliyetin birinci dalına evaluate olarak adlandırdığımız callExternalMethodActivity yerleştiriyoruz. Ve bu faaliyetin return özelliğine AcceptedEvaluation’ı bağlıyoruz.


private bool acceptedEvaluation;
public bool AcceptedEvaluation
{
    get { return acceptedEvaluation; }
    set { acceptedEvaluation = value; }
}

Diğer dala ise terminateActivity yerleştiriyoruz. evaluate faaliyetinin Condition özellliğini doldurmamız gerekiyor. Özelllikler bölümünde Condition ‘ a tıkladığımızda karşımıza 3 seçenek çıkıyor. None, Code Condition, Declarative Rule Condition. Code Condition için C# , Declarative Rule Condition için ise XML kullanmamız gerekmektedir. Declarative Rule Condition için karşımıza bir pencere çıkıyor ve bu pencerenin IntelliSense özelliği bulunduğu için işlemlerimizi rahatlıkla yapabilmekteyiz, MyWorkflowActivity.rule dosyası altında kayıt edilir.



ifElseActivity ‘nin diğer dalı içinde bir şart yazdıktan sonra iş akışımızın tasarımı tamamlanmış oldu. Bundan sonra yazdığımız IMyInterface arayüzününden türeyen bir sınıf yazacağız ki bu sınıf içindeki metod ve olaylar diğer uygulamalar ve sınıflar tarafından kullanılabilsin.

Bundan önceki makalemde de belittiğim gibi System.Workflow.Runtime isimuzayına ait en önemli sınıflerından birisi WorkflowRuntime sınıfıdır. WorkflowRuntime sınıfının AddService adlı bir metodu bulunmakta. Bu metoda parametre olarak vereceğimiz sınıf örnekleri iş akışımızın çalışma zamanında işlemesini etkileyen servisler sınıf örnekleridir. Bu servis sınıfı örnekleri Microsoft’ un kendi yazdığı servisler de olabilir, Microsoft’ un kendi yazdığı servislerden türeyen sınıflarda olabilir, kendi yazacağımız sınıflarda olabilir. Bu servisleri ister tek başlarına ister beraber kullanabiliriz. Biz bu örneğimizde IMyInterface arayüzününden türeteceğimiz sınıfı servis olarak kullanacağız.

Microsoft’ un kendi yazdığı servisler ise;

1. Scheduling Services
     a) DefaultWorkflowSchedulerService
     b) ManualWorkflowSchedulerService
2. Transaction Services
     a) DefaultWorkflowTransactionService
3. Persistence Services
     a) SqlWorkflowPersistenceService
4. Tracking Services
     a) SqlTrackingService

1. İş akışının çizelgeleme servisidir.
2. Transaction ‘ ların tutarlı biçimde işlemesini sağlayan servistir.
3. Bir iş akışı hemen işlemeyebilir, bir olayın gerçekleşmesini bekleyebilir (ayda bir yapılan bir iş için 30 gün). Bu süre içinde iş akışını bellekte tutmamızın bir yararı olmayacaktır. Bunu kalıcı bir yere saklayarak zamanı geldiğinde yine belleğe geri çağrıbiliriz. Sql Server için SqlWorkflowPersistenceService kullanılır.
4. İş akışının işlemesiyle ilgili bilgileri izleme ve kaydetme işlerini sağlayan servistir.


public class MyService : IMyInterface
{
    public event EventHandler<MyEventArgs> OfferAccepted;
    public event EventHandler<MyEventArgs> OfferRejected;
    public void OnOfferAccepted(Guid instanceID, Subscriber subscriber) {}
    public void OnOfferRejected(Guid instanceID, Subscriber subscriber) {}

    void IMyInterface.AcceptOffer(Guid offerID, Subscriber subscriber) {}
    void IMyInterface.RejectOffer(Guid offerID, Subscriber subscriber) {}
    bool IMyInterface.Evaluate() {}
}
MyService sınıfımız ImyInterface arayüzünden türediği için OfferAccepted ve OfferRejected olayları , AcceptOffer , RejectOffer ve Evaluate metodlarını implemente ediyor. Kapsüllemeyi bozmamak adına metodları IMyInterface.AcceptOffer(), void IMyInterface.RejectOffer ve bool IMyInterface.Evaluate() şeklinde “private” olarak implemete ediyoruz. Olaylarımızı doldurmak için OnOfferAccepted ve OnOfferRejected metodlarını kullanıyoruz.Metodların içinde iş mantıklarımızı yapıyoruz. Servis sınıfımızı yazdıktan sonra sıra geldi iş akışımızı test etmeye. Makalemizin başında resmi bulunan formu tasarlayacağız. Sınıfımızda WorkflowRuntime tipinde workflowRuntime ve MyService tipinde myService global nesne örnekleri bulunmakta. workflowRuntime nesne örneğine formun kurucu metodunda InitWorkflowRuntime metodu yardımıyla atama yapılıyor.

private WorkflowRuntime InitWorkflowRuntime()
{
    // Get a new workflow runtime
    WorkflowRuntime wr = new WorkflowRuntime();
    wr.WorkflowCompleted += new EventHandler<WorkflowCompletedEventArgs>(wr_WorkflowCompleted);
   
    // Add the external data service
    ExternalDataExchangeService dataService = new ExternalDataExchangeService();
    wr.AddService(dataService);
   
    // Add custom HelpDesk service
     myService = new MyService();
    dataService.AddService(myService);
   
    // Start
    wr.StartRuntime();
    return wr;
}
ExternalDataExchangeService tipinde bir nesne örneği yaratılıyor ve WorkflowRuntime tipindeki nesne örneğinin AddService metodu vasıtasıyla bu nesne örneğine ekleniyor. Ve myService nesne örneği de ExternalDataExchangeService tipindeki nesne örneğinin AddService metodu vasıtasıyla bu nesne örneğine ekleniyor.

Butonumuzun Click olayında ise ; Dictionary tipinde parameters nesne örneğine iş akışı ddl’imizdeki özellliklere bağlıyoruz. workflowRuntime nesne örneğinin CreateWorkflow metodu ile WorkflowInstance tipinde inst nesne örneği yaratılıyor. CreateWorkflow metodunun aldığı parametraler ise iş akışı sınıfımızın Type tipinde bir nesne örneği, parameters nesne örneği ve oluşturulan iş akışının Guid tipinde bir değişken alır. inst nesne örneğinin Start metodu kullanılarak iş akışı başlatılıyor. En son Evaluate metodu kullanılıyor.

Type type = typeof(MyWorkflowActivity);

Subscriber subscriber = new Subscriber();
subscriber.Accepted = rbAccept.Checked ? true : false;
subscriber.Name = txtName.Text;
subscriber.RateWeight = Convert.ToDouble(nud.Value);
subscriber.ID = Guid.NewGuid();
Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("Subscriber", subscriber);
parameters.Add("OfferID", subscriber.ID);

WorkflowInstance inst = workflowRuntime.CreateWorkflow(type, parameters, subscriber.ID);
inst.Start();

Evaluate(inst, subscriber);
Evaluate metodu ise OnOfferAccepted ve OnOfferRejected metodları kullanılmakta.

if (subscriber.Accepted)
{
    myService.OnOfferAccepted(workflowInstance.InstanceId, subscriber);
}
else
{
    myService.OnOfferRejected(workflowInstance.InstanceId, subscriber);
}
evaluate isimli faaliyetimizden dönen değeri ise WorkflowRuntime sınıfının WorkflowCompleted olayının EventArg’ının OutputParameters özelliği ile yakalıyoruz.

void wr_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)
{
    bool evaluation = Convert.ToBoolean(e.OutputParameters["AcceptedEvaluation"]);
    MessageBox.Show(string.Format("Offer is {0}", (evaluation) ? "accepted" : "rejected"));
}
İş akışımızda Activity sınıfından türeyen bir faaliyet de kullanalım. Activity sınıfının Execute adlı metodunu ezmemiz gerekecek. Bu metod ActivityExecutionStatus enum’ı tipinde bir değer döndürür. Eğer bu değeri “Closed” yapmazsak diğer faaliyetlere geçmeyecektir. Onun için “Closed” yapmalıyız.

public partial class MessageWriter : Activity
{
    protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
    {
        ShowMessage();
        return ActivityExecutionStatus.Closed;
    }
}
Sizlere Windows Workflow Foundation ‘ ı bir örnek ile anlatmaya çalıştım. Umarım yararlı bir makale olmuştur.

Kaynak dosyaları indirmek için tıklayınız.

Referanslar :
http://msdn.microsoft.com/msdnmag
http://www.codeproject.com
http://wf.netfx3.com/
Programming Windows Workflow Foundation: Practical WF Techniques and Examples using XAML and C# --- K. Scott Allen
Foundations of WF - An Introduction to Windows Workflow Foundation --- Brian R. Myers

Erdem ÖZDEMİR
[email protected]

Makale:
Windows Workflow Foundation Detay .NET 3.0 ve .NET 3.5 Özel Bölümü Erdem Özdemir
  • Yazılan Yorumlar
  • Yorum Yaz
MAY
24
2007
yanlış yazmamışım program (slash işaretini) sanırım ayıklıyor. Bu bilerek yapılan bir ozellik midir ?
MAY
24
2007
wca.exe DllAdi.dll o:KlasorAdi olacaktı o yanlış yazmışım. Saygılar
MAY
24
2007
makale güzel olmuş eline saglık hocam. Tek ekleyebilecegim nokta IMyInterfacedeki metod ve eventleri aktivite olarak oluştmak için wca.exe programını kullanırsak işimizin kolaylaşacagıdır. wca.exe (Interfacein tanımlı oldugu dll veya exe) o:AktivitelerinYazilacagiKlasor Boylece bizim Visual Studioda toolboxta bizim o metodlar ve eventler adıyla aktiviteler oluşmuş olacak ve interface ve metod propertileri atanmış olacaktır. Belki ileriki makalede yayınlayacaktınız hatırlatmak istedim. Saygılar
Sayfalar : 1 
Yorum yazabilmek için üye girişi yapmalısınız. Üye girişi için tıklayın.
Üye değilseniz Üyel Ol linkine tıklayarak üyeliğinizi hemen başlatabilirisniz.
 
  • Bu Konuda Son 10
  • Eklenen Son 10
  • Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor