C# İle Özelleştirilmiş Bir İş Akışı Otomasyonu Nasıl Yapılır?

C# İle Özelleştirilmiş Bir İş Akışı Otomasyonu Nasıl Yapılır?
C# İle Özelleştirilmiş Bir İş Akışı Otomasyonu Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Projeye başlamadan önce geliştirme ortamınızın güncel olduğundan emin olmalısınız. İhtiyacınız olan temel araçlar şunlardır:

  • .NET 9 SDK veya üzeri.
  • Visual Studio 2022 (sürüm 17.12+) veya Visual Studio Code (C# Dev Kit ile).
  • İş akışı yönetimi için temel tasarım desenleri (Strategy ve Command desenleri) hakkında bilgi.

Projenizi oluşturmak için terminal üzerinden şu komutu çalıştırarak bir konsol uygulaması başlatabilirsiniz:

dotnet new console -n IsAkisiOtomasyonu
cd IsAkisiOtomasyonu
dotnet add package Microsoft.Extensions.DependencyInjection

Bu komutlar, bağımlılık enjeksiyonu (Dependency Injection) kullanarak modüler bir yapı kurmamıza olanak tanıyacak temel kütüphaneyi projenize dahil eder.

Adım 1: İş Akışı Görevlerini Tanımlama

Otomasyonun temelinde, gerçekleştirilecek her bir işlemin standart bir arayüze sahip olması yatar. Bu, sisteminize yeni görevler eklerken mevcut kodunuzu değiştirmemenizi sağlar.

public interface IIsGorevi
{
    string GorevAdi { get; }
    Task CalistirAsync(object veri);
}

Bu arayüz, tüm iş akışı adımlarının uyması gereken sözleşmeyi belirler. CalistirAsync metodu, asenkron yapıda çalışarak uygulamanın kilitlenmesini önler.

Adım 2: Strateji Deseni ile İş Akışlarını Yönetme

Farklı iş akışlarını yönetmek için Strateji (Strategy) desenini kullanacağız. Bu desen, çalışma zamanında hangi görevin yürütüleceğini dinamik olarak seçmemize olanak tanır.

public class IsAkisiMotoru
{
    private readonly List _gorevler = new();

    public void GorevEkle(IIsGorevi gorev) => _gorevler.Add(gorev);

    public async Task Calistir(object veri)
    {
        foreach (var gorev in _gorevler)
        {
            await gorev.CalistirAsync(veri);
        }
    }
}

Bu motor sınıfı, tanımlanan görevleri sırasıyla çalıştırır. GorevEkle metodu ile akışa yeni adımlar enjekte edebilirsiniz.

Adım 3: Somut Görevlerin Uygulanması

Şimdi, örnek bir dosya işleme ve loglama görevi oluşturalım. Bu görevler, arayüzümüzü uygulayarak iş akışına dahil olur.

public class DosyaKontrolGorevi : IIsGorevi
{
    public string GorevAdi => "Dosya Kontrol";

    public async Task CalistirAsync(object veri)
    {
        // Dosya varlığı kontrolü mantığı
        await Task.Delay(100); 
        Console.WriteLine($"{GorevAdi} tamamlandı.");
    }
}

Bu sınıf, IIsGorevi arayüzünü uygular. Gerçek bir senaryoda burada dosya sistemine erişim veya veritabanı sorguları yer alacaktır.

Adım 4: İş Akışını Yapılandırma ve Çalıştırma

Şimdi tüm parçaları bir araya getirelim. Programın giriş noktasında (Program.cs) iş akışımızı oluşturup tetikleyelim.

var motor = new IsAkisiMotoru();
motor.GorevEkle(new DosyaKontrolGorevi());

await motor.Calistir("Test Verisi");

Bu kod bloğu, otomasyon motorunu başlatır ve tanımlanan görevleri sırayla yürütür. Bağımlılık enjeksiyonu kullanarak bu motoru daha geniş uygulamalara taşıyabilirsiniz.

Adım 5: Hata Yönetimi ve Güvenlik Önlemleri

Otomasyon süreçlerinde hata yönetimi hayati önem taşır. Bir görev başarısız olduğunda tüm akışın durmaması için try-catch blokları kullanmalısınız.

public async Task CalistirGuvenli(object veri)
{
    foreach (var gorev in _gorevler)
    {
        try {
            await gorev.CalistirAsync(veri);
        }
        catch (Exception ex) {
            Console.WriteLine($"Hata oluştu: {ex.Message}");
        }
    }
}

Kritik Güvenlik Uyarısı: Otomasyon süreçlerinde dışarıdan alınan verileri (dosya yolları, kullanıcı girdileri) asla doğrudan işlemeyin. Girişleri her zaman doğrulayın (Input Validation) ve dosya yolu manipülasyonlarına (Path Traversal) karşı güvenlik önlemleri alın.

İş Akışı Yöntemlerinin Karşılaştırılması

Yöntem Avantaj Dezavantaj
Strategy Deseni Yüksek esneklik Karmaşık yapı
Hard-coded Akış Basit uygulama Sürdürülebilirlik düşük
Event-Driven Ölçeklenebilir Debug süreci zor

Sıkça Sorulan Sorular

İş akışında verileri görevler arasında nasıl taşırım?

Görevler arasında veri taşımak için bir "Context" (Bağlam) nesnesi oluşturabilir ve bunu CalistirAsync metoduna parametre olarak geçebilirsiniz.

Asenkron yapı neden önemlidir?

Asenkron yapı, özellikle G/Ç (I/O) yoğun işlemlerde uygulamanın donmasını engeller ve kaynak kullanımını optimize eder.

Bu yapı veritabanı işlemleri için güvenli mi?

Evet, ancak veritabanı işlemlerinde mutlaka Entity Framework Core gibi güvenli ORM araçlarını kullanmalı ve SQL injection riskine karşı parametreli sorgular tercih etmelisiniz.

İş akışını nasıl izleyebilirim?

Microsoft.Extensions.Logging kütüphanesini kullanarak her görev başlangıcında ve bitişinde loglama yapabilirsiniz.

Daha karmaşık otomasyonlar için kütüphane önerisi var mı?

Evet, çok daha karmaşık ve görselleştirilebilir iş akışları için "Elsa Workflows" gibi açık kaynaklı .NET kütüphanelerini inceleyebilirsiniz.

İş Akışı Otomasyonunda Performans Optimizasyonu ve Ölçeklendirme

Geliştirdiğiniz iş akışı motoru, görev sayısı arttıkça veya eşzamanlı istekler yükseldikçe darboğazlarla karşılaşabilir. Performansı optimize etmek için sadece asenkron programlama yeterli değildir; kaynak yönetimi ve iş parçacığı (thread) havuzunun verimli kullanılması kritik öneme sahiptir.

İş Akışlarında Paralel İşleme Stratejileri

Eğer bir iş akışındaki görevler birbirine bağımlı değilse, bunları sırayla çalıştırmak yerine Task.WhenAll kullanarak paralel çalıştırabilirsiniz. Bu, toplam işlem süresini ciddi oranda düşürür.

public async Task ExecuteParallelTasks(List tasks, WorkflowContext context)
{
    var tasksToRun = tasks.Select(t => t.ExecuteAsync(context));
    await Task.WhenAll(tasksToRun);
}

Ancak, paralel işlem yaparken veritabanı bağlantı havuzu (connection pool) sınırlarını aşmamaya dikkat etmelisiniz. Çok sayıda eşzamanlı işlem, veritabanı tarafında kilitlenmelere (deadlock) yol açabilir. Bu gibi durumlarda SemaphoreSlim kullanarak aynı anda çalışan görev sayısını sınırlayabilirsiniz.

private static readonly SemaphoreSlim _semaphore = new SemaphoreSlim(5); // Aynı anda en fazla 5 görev

public async Task ExecuteThrottledTask(IWorkflowTask task, WorkflowContext context)
{
    await _semaphore.WaitAsync();
    try
    {
        await task.ExecuteAsync(context);
    }
    finally
    {
        _semaphore.Release();
    }
}

İş Akışları İçin Birim Testi ve Hata Ayıklama Teknikleri

Otomasyon sistemlerinde en büyük zorluk, karmaşık iş akışlarının nasıl test edileceğidir. İş akışınızın her bir adımını izole etmek için "Mocking" kütüphaneleri (Moq veya NSubstitute) kullanmak, sistemin kararlılığını artırır.

Mocking ile İş Akışı Testi

Görevlerinizi arayüzler (interface) üzerinden tasarladığınız için, test ortamında gerçek bir veritabanı veya API çağırmak yerine sahte verilerle (mock) süreci simüle edebilirsiniz.

[Fact]
public async Task Workflow_Should_Execute_All_Steps()
{
    // Arrange
    var mockTask = new Mock();
    mockTask.Setup(t => t.ExecuteAsync(It.IsAny()))
            .Returns(Task.CompletedTask);

    var workflow = new WorkflowEngine();
    workflow.AddTask(mockTask.Object);

    // Act
    await workflow.RunAsync(new WorkflowContext());

    // Assert
    mockTask.Verify(t => t.ExecuteAsync(It.IsAny()), Times.Once);
}

İzlenebilirlik (Observability) İçin Logging

İş akışları hata verdiğinde, hangi adımda ve hangi verilerle başarısız olduğunu anlamak için yapılandırılmış loglama (structured logging) kullanmalısınız. Microsoft.Extensions.Logging kullanarak her görev başlangıcında ve bitişinde bağlamsal verileri kaydedin:

public async Task ExecuteAsync(WorkflowContext context)
{
    _logger.LogInformation("Görev başlatılıyor: {TaskId}", context.CurrentTaskId);
    try 
    {
        // İş mantığı
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Görev başarısız oldu: {TaskId}", context.CurrentTaskId);
        throw;
    }
}

Bu yöntem, karmaşık iş akışlarında hata ayıklama süresini dakikalardan saniyelere indirecektir. Üretim ortamında bu logları Serilog veya Application Insights gibi araçlara yönlendirerek merkezi bir izleme paneli oluşturmanız önerilir.

Sonuç

C# ile özelleştirilmiş bir iş akışı otomasyonu yapmak, projenizin modülerliğini ve yönetilebilirliğini artırır. Bu rehberde öğrendiğiniz Strategy deseni ve arayüz tabanlı yaklaşım, profesyonel yazılım geliştirme standartlarına uygun bir temel sunar. Bir sonraki adım olarak, bu yapıyı bir veritabanı ile entegre ederek "durum bilgisi olan" (stateful) iş akışları geliştirmeyi deneyebilirsiniz.

Sorumluluk Reddi: Bu makaledeki kod örnekleri eğitim amaçlıdır. Üretim ortamında kullanmadan önce mutlaka birim testleri yazılmalı, güvenlik denetimleri yapılmalı ve hata yönetimi mekanizmaları genişletilmelidir.

Bu yazıya tepkinizi paylaşın:
Selin Demir

Sürdürülebilir yaşam ve kişisel verimlilik üzerine odaklanan bir içerik üreticisiyim. Zaman yönetimi ve organizasyonel ipuçları konusunda okuyuculara yol gösteriyorum.

Yorumlar (0)

Yorum Yaz