Skip to content

eren0b/UstaPlatform

Repository files navigation

Proje: UstaPlatform - Şehrin Uzmanlık Platformu

Bu proje, "Nesne Yönelimli Programlama (NYP) ve İleri C#" dersi kapsamında geliştirilmiş bir uzman-vatandaş eşleştirme platformu simülasyonudur. Arcadia şehrindeki vatandaş taleplerini (Tesisatçı, Elektrikçi vb.) alır, uygun ustayla eşleştirir, dinamik fiyatlama yapar ve rota planlar.

Projenin temel amacı, katı kodlanmış bir yapı yerine, SOLID prensiplerine (özellikle Açık/Kapalı Prensibi - OCP) uygun, genişletilebilir ve "Plug-in" (Eklenti) tabanlı bir fiyatlama mimarisi kurmaktır.

1. Kurulum ve Çalıştırma

Proje, Visual Studio 2022 ve .NET 8 (veya .NET 6+ uyumlu) ortamında geliştirilmiştir.

A. Projenin Derlenmesi

Projeyi Visual Studio ile açın (UstaPlatform.sln).

Solution Explorer'da en üstteki **"Solution 'UstaPlatform'"**a sağ tıklayın.

Build Solution (Çözümü Derle) seçeneğine tıklayın. Bu adım, tüm projelerin (.dll dosyalarının) oluşturulmasını sağlayacaktır.

B. Eklentilerin (Plug-in) Hazırlanması

Projenin "Plug-in" mimarisinin çalışması için, kural DLL'lerinin motorun (PricingEngine) okuyacağı Plugins klasörüne manuel olarak kopyalanması gerekmektedir.

Ana uygulama klasörüne gidin:

Solution Explorer'da UstaPlatform.App projesine sağ tıklayın.

Open Folder in File Explorer (Dosya Gezgini'nde Klasörü Aç) seçeneğine tıklayın.

bin/Debug/net... (örn: net8.0) klasörüne gidin. UstaPlatform.App.exe dosyasının bulunduğu yer burasıdır.

Bu klasörün içinde Plugins adında yeni bir klasör oluşturun. (Eğer programı bir kez çalıştırırsanız, Program.cs içindeki kod bu klasörü otomatik olarak oluşturacaktır).

İlk Kuralı Kopyalayın:

UstaPlatform.Rules.WeekendFee projesinin bin/Debug/net... klasörüne gidin.

UstaPlatform.Rules.WeekendFee.dll dosyasını kopyalayın.

Bu dosyayı, Adım 2'de bulduğunuz UstaPlatform.App/.../Plugins klasörünün içine yapıştırın.

C. Demo Senaryosunun Çalıştırılması

Demo Bölüm 1:

Visual Studio'dan UstaPlatform.App projesini başlatın (Yeşil 'Start' butonu).

Program çalışacak, Plugins klasöründeki UstaPlatform.Rules.WeekendFee.dll'i bulacak ve "KURAL YÜKLENDİ: Hafta Sonu Ek Ücreti" mesajını gösterecektir.

Senaryo 1 için 500 TL'lik temel fiyatı, Hafta Sonu kuralı (%20) ile çarparak Nihai Fiyat: 600,00 TL olarak hesaplayacaktır.

Program, "DEMO BÖLÜM 2"ye gelerek sizden yeni bir kural eklemenizi isteyecek ve konsolda beklemeye geçecektir.

Demo Bölüm 2 (Dinamik Yükleme):

Program konsolda beklerken, UstaPlatform.Rules.LoyaltyDiscount projesinin bin/Debug/net... klasörüne gidin.

UstaPlatform.Rules.LoyaltyDiscount.dll dosyasını kopyalayın.

Bu dosyayı da Plugins klasörüne (diğer .dll'in yanına) yapıştırın.

Çalışmakta olan konsol ekranına geri dönüp ENTER tuşuna basın.

Sonuç:

Program devam edecek, Fiyatlama Motoru (PricingEngine) yeniden başlatılacak ve Plugins klasörünü tekrar tarayacaktır.

Bu kez iki kuralı da (WeekendFee ve LoyaltyDiscount) yükleyecektir.

Senaryo 2'de fiyatı yeniden hesaplayacaktır:

Temel Fiyat: 500 TL

Kural 1 (Hafta Sonu): 500 * 1.20 = 600 TL

Kural 2 (Sadakat İnd.): 600 * 0.90 = 540 TL

Ekranda Nihai Fiyat: 540,00 TL gösterilecektir. Bu, ana uygulama kodu (UstaPlatform.App) değişmeden sisteme yeni bir işlevsellik eklendiğini kanıtlar.

2. Tasarım Kararları ve Mimari

Proje, SOLID prensiplerini temel alan, "Soğan Mimarisi"ne (Onion Architecture) benzer katmanlı bir yapı kullanılarak tasarlanmıştır. Amaç, bağımlılıkları en aza indirmek ve esnekliği en üst düzeye çıkarmaktır.

A. Katmanlı Mimari (Proje Yapısı)

Çözüm (Solution), sorumlulukları net bir şekilde ayırmak (SRP) için birden fazla projeye bölünmüştür:

UstaPlatform.Domain (Arşiv Odası):

Mimarinin kalbidir. Projenin temel varlıklarını (Usta, Talep, IsEmri, Schedule, Route vb.) barındırır.

Dış katmanlara (Infrastructure, App) hiçbir bağımlılığı yoktur. Sadece saf C# kodudur.

UstaPlatform.Pricing (Kural Kitapçığı):

Projenin "sözleşmelerini" (arayüzlerini) tanımlar.

IPricingRule arayüzü burada bulunur. Bu katman, "Eklenti Mimarisi" için DIP (Bağımlılıkların Tersine Çevrilmesi) prensibini uygular.

Sadece Domain katmanına bağımlıdır (örn: IPricingRule, IsEmri'yi kullanır).

UstaPlatform.Infrastructure (Operasyon Departmanı):

Asıl "işi yapan" sınıfları barındırır.

Ödevin kalbi olan PricingEngine (Fiyatlama Motoru) ve StaticHelpers (Yardımcı Sınıflar) buradadır.

Domain ve Pricing katmanlarına bağımlıdır.

UstaPlatform.App (Giriş Lobisi / Kullanıcı Arayüzü):

Kullanıcının gördüğü son katmandır (Console Uygulaması).

Tüm akışı yönetir, test verilerini oluşturur ve Infrastructure katmanındaki servisleri (örn: PricingEngine) çağırır.

Rules.* Projeleri (örn: UstaPlatform.Rules.WeekendFee):

Bunlar ana uygulamadan tamamen bağımsız, "Eklenti" (Plug-in) projeleridir.

Kesinlikle App veya Infrastructure projelerini tanımazlar.

Sadece "Kural Kitapçığı"na (Pricing) ve "Arşiv"e (Domain) bağımlıdırlar.

B. SOLID Prensipleri Uygulamaları

S - Tek Sorumluluk Prensibi (SRP): Her sınıfın ve projenin tek bir sorumluluğu vardır. PricingEngine sadece kuralları yükler ve fiyat hesaplar. Usta sınıfı sadece usta verisini tutar. WeekendFeeRule sadece hafta sonu kuralını hesaplar.

O - Açık/Kapalı Prensibi (OCP): Bu, projenin en kritik gereksinimidir ve Plug-in Mimarisi ile sağlanmıştır.

PricingEngine sınıfı, yeni bir fiyat kuralı (örn: "Bayram İndirimi") eklendiğinde değiştirilmeye kapalıdır.

Ancak, IPricingRule arayüzünü uygulayan yeni DLL'lerin Plugins klasörüne atılmasıyla yeni kurallara (genişlemeye) açıktır.

D - Bağımlılıkların Tersine Çevrilmesi (DIP): Üst katmanlar, alt katmanlardaki somut sınıflara değil; soyutlamalara (arayüzlere) bağımlıdır.

UstaPlatform.Infrastructure (üst katman), UstaPlatform.Rules.WeekendFee (alt katman/eklenti) projesini tanımaz ve ona referans vermez.

Bunun yerine, her ikisi de UstaPlatform.Pricing (soyutlama katmanı) içindeki IPricingRule arayüzüne bağımlıdır. PricingEngine, somut WeekendFeeRule sınıfını değil, sadece soyut IPricingRule sözleşmesini bilir.

C. En Kritik Kısım: Plug-in (Eklenti) Mimarisi Nasıl Çalışır?

Bu mimari, ana programın (UstaPlatform.App) kodunu değiştirmeden veya yeniden derlemeden sisteme yeni fiyatlandırma kuralları eklememizi sağlar.

Sözleşme (Interface): UstaPlatform.Pricing projesindeki IPricingRule arayüzü, tüm eklentilerin uymak zorunda olduğu resmi "sözleşmedir". Bu sözleşme, her kuralın bir RuleName (Ad) ve bir CalculatePrice (Hesaplama Metodu) sağlamasını zorunlu kılar.

Bağımsız Eklentiler (DLL'ler): UstaPlatform.Rules.WeekendFee gibi her kural, bu IPricingRule sözleşmesini uygulayan ayrı bir "Class Library" projesidir.

Motor (PricingEngine) ve "Reflection": UstaPlatform.Infrastructure içindeki PricingEngine sınıfı, başlatıldığında (new PricingEngine(pluginPath)), kendisine verilen Plugins klasörünü tarar.

Yükleme (Assembly Loading): Motor, C#'ın Reflection (Yansıma) kütüphanesini kullanarak klasördeki her bir .dll dosyasını hafızaya yükler (Assembly.LoadFrom).

Aktivasyon (Activation): Yüklediği .dll içindeki tüm sınıfları (tipleri) inceler ve IPricingRule sözleşmesini uygulayan sınıfları bulur (typeof(IPricingRule).IsAssignableFrom(t)).

Çalıştırma: Bulduğu bu sınıflardan Activator.CreateInstance ile birer nesne yaratır ve bunları kendi içindeki _rules listesine ekler. engine.CalculatePrice metodu çağrıldığında, bu listedeki tüm kuralları sırayla (kompozisyon şeklinde) çalıştırır.

Bu tasarım sayesinde, yarın "Acil Çağrı Ücreti" adında yeni bir kural projesi oluşturup derlemek ve .dll dosyasını Plugins klasörüne atmak, sistemin bu kuralı otomatik olarak tanıması için yeterlidir.

3. Kullanılan İleri C# Özellikleri

Projede, ödev gereksinimlerini karşılamak için modern C# özellikleri de kullanılmıştır:

init-only Özelliği: Talep ve IsEmri sınıflarında Id ve KayitZamani gibi alanların değiştirilemez (immutable) olması için init kullanılmıştır. Bu alanlar sadece nesne yaratılırken atanabilir.

Nesne ve Koleksiyon Başlatıcılar: Program.cs içinde test verisi oluşturulurken (new Usta { ... }) ve Route sınıfı kullanılırken (new Route { {10, 20}, ... }) kod okunabilirliğini artırmak için bu başlatıcılar yoğun olarak kullanılmıştır.

Dizinleyici (Indexer): Schedule (Çizelge) sınıfı, Usta takvimine benimTakvimim[DateOnly.Today] şeklinde sezgisel bir erişim sağlamak için bir dizinleyici (this[DateOnly gun]) uygular.

Özel IEnumerable Koleksiyonu: Route (Rota) sınıfı, IEnumerable<(int X, int Y)> arayüzünü uygulamıştır. Ayrıca Add(int X, int Y) metodu eklenerek koleksiyon başlatıcıları desteklemesi sağlanmıştır. Bu sayede foreach ile gezilebilir.

static Sınıflar: Guard (Doğrulama) ve MoneyFormatter (Para Formatlayıcı) gibi genel hizmetler, bir "alet çantası" gibi çalışmaları için static sınıflar olarak tasarlanmıştır.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages