> For the complete documentation index, see [llms.txt](https://bekoturko.gitbook.io/yazilim-gelistirme-wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bekoturko.gitbook.io/yazilim-gelistirme-wiki/uygulama-yapisi-ve-katmanlari/untitled.md).

# Business Domain - İş Alanı

İş Mantığı Katmanı

## İş Mantığı Katmanı

Bu belge geliştirilen uygulamaların sahip olması beklenen katmanları ve çalışma mantıklarını, projelerin organizasyonu gibi konuları içerir.

### Açıklama

Bu kılavuz projelerin iş mantığı (business logic) katmanının oluşturulması ve yönetilmesi ile ilgili konuları içerir.

### Tanım

* İş katmanı (business domain) iş modelleri ve bunların üzerinde işlem yapan, iş kurallarını uygulayan servislerden ve factory sınıflarından oluşur. (*Business* + *Model* projeleri iş katmanını oluşturur.)
* İş katmanı, onu kullanan uygulamanın değiştirilmesi veya yeni bir uygulama oluşturulması durumunda (örneğin bir web uygulamasının mobil uygulamaya çevrilmesi ya da web uygulamasının yanına bir de API uygulaması eklenmesi) bile çalışabilecek şekilde tasarlanmalıdır.
* İş katmanı teknolojiden bağımsız olmalıdır. Genel işleri yapan, teknoloji-bağımlı işlemler *Framework* projesinde oluşturulabilir.
* İş katmanında işlem metotlarının sonuç bilgisi başarı durumunu içeriyorsa ServiceResult ve benzeri sınıflarla döndürülmeli. `boolean`, `int` gibi primitif tipler kullanılmamalı.

### BaseService / BaseValidator

Servis sınıfları `BaseService` temel sınıfından türetilir.\
Validatör sınıfları `BaseValidator` temel sınıfından türetilir.\
Bu şekilde bu sınıflar temel sınıflarındaki yardımcı metotları kullanabilir hale gelirler. (Örneğin loglama işlemlerinde kullanılan `SetMethodNameForLogMessage` metodu.)

### Metotlar arası iletişim / ServiceResult kullanımı

İşlem yapan metotlar işlem sonucunu `ServiceResult` tipinde döndürür.

```csharp
public class ServiceResult
{
    public bool IsSuccess{ get; set; }
    
    public string ErrorMessage { get; set; }
}
```

Veri geçerliliği kontrollerinde `ValidationResult` tipi kullanılır.

```csharp
public class ValidationResult
{
    public bool IsValid { get; set; }
    
    public string ValidationErrorMessage { get; set; }
}
```

Authorization kontrollerinde `AuthorizationResult` tipi kullanılır.

```csharp
public class AuthorizationResult
{
    public bool IsAllowed { get; set; }
    
    public string ErrorMessage { get; set; }
}
```

Bu özel sonuç tiplerinin başarı ve hata durumlarına özel yardımcı metotları `BaseService` temel sınıfından kullanılır. Yani bu sonuç sınıfları hiçbir zaman elle oluşturulmaz.

`BaseValidator` sınıfında da `ValidationResult` sonucu oluşturma yardımcı metotları bulunur.

Bu bilgilerden daha fazla bilgi döndürmenin gerektiği durumlarda ServiceResult sınıfından türeyen *özel* sonuç sınıfları kullanılır.

```csharp
public class LikeShareResult : ServiceResult
{
    public ShareLikeInfo ShareLikeInfo { get; set; }
}
```

### Transaction yönetimi

Önceden iş katmanında başlatılan bir veritabanı transactionın hata durumunda geri alınabilmesi için veri katmanında hata oluşursa hatanın `throw` edilmesi gerekliliği vardı. Bu kullanım örtülü ve kolay anlaşılmayan bir yöntemdi.\
Yeni kullanım şekli veri katmanının hiçbir zaman hata fırlatmaması, sonuç bilgilerine bu hatayı yansıtması, iş katmanının da bu işlemlerin sonucuna bakarak işlemi geri alıp almamaya karar vermesi.\
Transactionın içinde veri katmanı yerine private metotlar veya başka bir servisin metodu çağrılıyorsa, bu metodun transaction içinde kullanıldığını belirten bir seçenek ve kullanıldığı durumda da hata oluşursa `TransactionIstopException` adında bir hata fırlatması sağlandı.\
Bu durumda da transaction geri alınıyor.

İşlemin geri alınmasına neden olacak bir koşul sağlandığında hata fırlatma örneği `TransactionScope` içinde hata fırlatma örneği. (Sonuç: İşlemler geri alınır.)

```csharp
//TRANSACTION BAŞLANGIÇ
using (TransactionScope scope = TransactionScopeFactory.CreateTransactionScope())
{
    // ortak şikayet bilgilerini kaydet
    complaint.ComplaintId = complaintRepository.AddComplaint(complaint);

    if (complaint.ComplaintId == 0)
    {
        throw new TransactionIstopException("Şikayeti kaydetme işlemi başarısız.");
    }

...
```

Bir veritabanı işlemi veya servis metodu başarısız sonuç döndürürse `TransactionScope` içinde hata fırlatma örneği. (Sonuç: İşlemler geri alınır.)

```csharp
//oturum açma işlemini logla
bool isLogSucceeded = memberService.LogMemberLogOn(memberLog);

if (!isLogSucceeded)
{
    throw new TransactionIstopException("Üye girişi loglama işlemi başarısız.");
}
```
