BulutBusiness.Core 10.1.1

dotnet add package BulutBusiness.Core --version 10.1.1
                    
NuGet\Install-Package BulutBusiness.Core -Version 10.1.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="BulutBusiness.Core" Version="10.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="BulutBusiness.Core" Version="10.1.1" />
                    
Directory.Packages.props
<PackageReference Include="BulutBusiness.Core" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add BulutBusiness.Core --version 10.1.1
                    
#r "nuget: BulutBusiness.Core, 10.1.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package BulutBusiness.Core@10.1.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=BulutBusiness.Core&version=10.1.1
                    
Install as a Cake Addin
#tool nuget:?package=BulutBusiness.Core&version=10.1.1
                    
Install as a Cake Tool

BulutBusiness.Core

.NET 10 tabanlı kurumsal iş uygulamaları için paylaşımlı altyapı kütüphanesi. Clean Architecture, CQRS ve Repository Pattern prensiplerine uygun olarak tasarlanmıştır.


Kurulum

dotnet add package BulutBusiness.Core

Modüller

Persistence — Repository & Entity

Generic EF Core repository implementasyonu. Tüm CRUD operasyonları, soft delete, sayfalama ve dinamik filtreleme desteklenir.

// Entity base sınıfı
public class Order : Entity<int> { ... }

// Repository
public class OrderRepository : EfRepositoryBase<Order, int, AppDbContext>, IOrderRepository { }

EfRepositoryBase<TEntity, TEntityId, TContext> metodları:

Metod Açıklama
AddAsync Ekle (CreatedDate otomatik set edilir)
UpdateAsync Güncelle (UpdatedDate otomatik set edilir)
DeleteAsync Sil — permanent: true kalıcı, varsayılan soft delete
GetAsync Tek kayıt getir
GetListAsync Sayfalı liste getir
GetListByDynamicAsync Dinamik filtreli liste
AnyAsync Varlık kontrolü

Soft Delete: DeletedDate set edilerek kayıt gizlenir. Cascade soft delete ilişkili kayıtlara otomatik uygulanır.

Timestamp davranışı: CreatedDate, UpdatedDate, DeletedDate alanları DateTimeOffset tipindedir ve DateTimeOffset.UtcNow ile set edilir. Sunucu/container saat dilimi ayarından bağımsızdır; yerel saat gösterimi client (web/mobil) tarafında kullanıcının bölgesine göre yapılmalıdır.

Sayfalama:

var result = await _orderRepository.GetListAsync(
    predicate: o => o.Status == OrderStatus.Active,
    orderBy: q => q.OrderByDescending(o => o.CreatedDate),
    index: 0,
    size: 20
);
// result.Items, result.Count, result.Pages, result.HasNext

Dinamik filtreleme:

var result = await _repository.GetListByDynamicAsync(
    dynamic: new DynamicQuery
    {
        Filter = new Filter { Field = "Status", Operator = "eq", Value = "1" },
        Sort = [new Sort { Field = "CreatedDate", Dir = "desc" }]
    }
);

Security — JWT & Kimlik Doğrulama

JWT token üretimi, refresh token yönetimi, şifre hashleme ve iki faktörlü kimlik doğrulama (Email OTP / TOTP).

// appsettings.json
{
  "TokenOptions": {
    "Audience": "myapp.com",
    "Issuer": "myapp.com",
    "AccessTokenExpiration": 60,
    "SecurityKey": "your-secret-key-min-32-chars"
  }
}
// Program.cs
builder.Services.AddSecurityServices();

Bileşenler:

Bileşen Açıklama
JwtHelper JWT access token üretir
HashingHelper HMACSHA512 ile şifre hash/verify
EmailAuthenticatorHelper E-posta OTP kodu üretir
OtpNetOtpAuthenticatorHelper TOTP (Google Authenticator uyumlu)
BearerSecurityRequirementOperationFilter Swagger'a otomatik Bearer ekler

Hazır Security Entity'leri: User, OperationClaim, UserOperationClaim, RoleGroup, RoleGroupOperationClaim, UserRoleGroup, RefreshToken, EmailAuthenticator, OtpAuthenticator

Yetki Grubu (RoleGroup)

10.0.7 ile eklenen grup tabanlı yetkilendirme sistemi. Kullanıcılara tek tek claim atamak yerine, claim'leri gruplar halinde yönetip kullanıcılara gruplar atanabilir. Bir kullanıcı birden fazla gruba üye olabilir; token oluşturulurken tüm grupların claim'leri düzleştirilerek (flatten) birleştirilir.

RoleGroup ("Satın Alma Yöneticisi")
  ├─ PurchaseQuotes.Read
  ├─ PurchaseQuotes.Create
  └─ PurchaseInvoices.Read

Kullanıcı: Ahmet
  ├─ Grup: "Satın Alma Yöneticisi"
  └─ Grup: "Stok Görevlisi"

Token'daki roller (flatten + distinct):
  ["PurchaseQuotes.Read", "PurchaseQuotes.Create", "PurchaseInvoices.Read", "Stock.Read", ...]
// Domain'de extend et (navigation property'ler burada tanımlanır)
public class RoleGroup : RoleGroup<Guid> { }
public class RoleGroupOperationClaim : RoleGroupOperationClaim<Guid, Guid, int> { }
public class UserRoleGroup : UserRoleGroup<Guid, Guid, Guid> { }
// Token oluştururken — ITokenHelper overload
var directClaims   = await _userOpClaimRepo.GetClaimsAsync(userId);
var userGroups     = await _userRoleGroupRepo.GetGroupsAsync(userId);
var groupClaims    = await _roleGroupClaimRepo.GetClaimsByGroupsAsync(groupIds);

var token = _tokenHelper.CreateToken(user, directClaims, userGroups, groupClaims);

Pasif grup davranışı: IsActive = false olan gruplar token'a claim eklemez; bu sayede bir grubun tüm kullanıcı yetkilerini tek seferde askıya alabilirsiniz.


Application — CQRS Pipeline Behavior'ları

MediatR pipeline üzerinde çalışan cross-cutting concern davranışları.

Behavior Interface Açıklama
AuthorizationBehavior ISecuredRequest Rol/claim tabanlı yetkilendirme
CachingBehavior ICachableRequest In-memory önbellekleme
CacheRemovingBehavior ICacheRemoverRequest Cache invalidation
LoggingBehavior ILoggableRequest İstek/yanıt loglama
PerformanceBehavior IIntervalRequest Yavaş sorgu uyarısı
TransactionScopeBehavior ITransactionalRequest Transaction scope
RequestValidationBehavior — FluentValidation entegrasyonu
// Yetkilendirme örneği
public class DeleteProductCommand : IRequest<Unit>, ISecuredRequest
{
    public string[] Roles => ["Admin", "Manager"];
}

// Önbellekleme örneği
public class GetProductsQuery : IRequest<GetListResponse<ProductDto>>, ICachableRequest
{
    public string CacheKey => "Products";
    public TimeSpan? SlidingExpiration => TimeSpan.FromMinutes(30);
}

Mailing — E-posta Gönderimi

MailKit tabanlı HTML e-posta gönderimi.

// appsettings.json
{
  "MailSettings": {
    "Server": "smtp.example.com",
    "Port": 587,
    "SenderFullName": "example",
    "SenderEmail": "noreply@example.com",
    "UserName": "noreply@example.com",
    "Password": "app-password",
    "UseSsl": false
  }
}
await _mailService.SendEmailAsync(new Mail
{
    Subject = "Siparişiniz alındı",
    HtmlBody = "<h1>Teşekkürler!</h1>",
    ToList = [new ToEmail { Address = "customer@example.com", Name = "Ad Soyad" }]
});

ElasticSearch

NEST tabanlı ElasticSearch entegrasyonu. Index oluşturma, belge ekleme/güncelleme, arama işlemleri.

// appsettings.json
{
  "ElasticSearchConfig": {
    "ConnectionString": "http://localhost:9200",
    "UserName": "",
    "Password": ""
  }
}

Localization — Çoklu Dil Desteği

İki farklı lokalizasyon stratejisi:

  • ResourceLocalizationManager — .resx dosyası tabanlı, yerel çeviri
  • AmazonTranslateLocalizationManager — AWS Translate ile otomatik çeviri
  • TranslateLocalizationManager — Karma strateji
// Program.cs
app.UseMiddleware<LocalizationMiddleware>(); // Accept-Language header'ına göre dil ayarlar

CrossCuttingConcerns — Hata Yönetimi & Loglama

Exception Middleware: BusinessException, AuthorizationException, NotFoundException, ValidationException tiplerini yakalar ve RFC 7807 uyumlu ProblemDetails döner.

Serilog Loglama:

// appsettings.json
{
  "SeriLogConfigurations": {
    "FileLogConfiguration": {
      "FolderPath": "/logs"
    }
  }
}

Versiyon Geçmişi

10.1.1

  • Hata düzeltmesi — yerelleştirme, bölgesel kültür: Accept-Language: tr-TR artık *.tr.yaml kaynağına düşer (tr-TR → tr). Önceden bölgesel kültür hiçbir dosyayla eşleşmiyor, doğrudan varsayılan dile (en) geçiliyordu — tr-TR gönderen tarayıcılarda tüm iş kuralı mesajları İngilizce çıkıyordu. Kültür adları büyük/küçük harf duyarsız.
  • Hata düzeltmesi — dinamik filtre, harf duyarsız metin araması (10.1.0 regresyonu): aranan değer ifade içinde ToLower() ile bırakılıyordu; EF bu sabit alt-ifadeyi istemcide sunucu kültürüyle hesapladığından tr-TR sunucuda "I" → "ı" oluyor, SQL LOWER ise "i" üretiyordu → büyük I içeren aramalar ("MUHTELIF", "KIRMIZI") sonuç vermiyordu. Değer artık ToLowerInvariant ile küçültülüyor; sütun sağlayıcıda LOWER. Türkçe'ye özgü İ/ı eşlemesi (ör. "İstanbul" ↔ "istanbul") uygulamanın sorumluluğundadır.

10.1.0

Hata düzeltme sürümü; davranış değiştiren (kırıcı) maddeler [KIRICI] ile işaretli.

  • Dinamik filtre (ToDynamic) yeniden yazıldı
    • Değerler alanın tipine çevrilir: sayılar, bool (true/false/1/0), Guid, enum (ad ya da sayı), DateTime, DateTimeOffset (offset yoksa sunucu yerel saati), DateOnly, TimeOnly, TimeSpan ve nullable karşılıkları. Önceden nullable alanlarda ve Guid/enum/tarih alanlarında ifade kurulamıyordu.
    • [KIRICI] Sayılar önce Invariant kültürle katı ayrıştırılır: tr-TR sunucuda "12.5" artık 125 değil 12.5.
    • [KIRICI] Geçersiz alan/operatör/değer ArgumentException (500) yerine ValidationException (400) fırlatır.
    • Alanı boş düğüm saf grup olarak çalışır ({ logic: "or", filters: [...] }). Alanı dolu düğümde sözleşme aynı: kök koşul AND (çocuklar).
    • contains/startswith/endswith yalnız metin alanlarında; CaseSensitive=false (varsayılan) artık gerçekten uygulanır (iki taraf LOWER) — PostgreSQL gibi harmanlaması duyarlı sağlayıcılarda da aynı sonuç. Null metin eşleşmez.
    • isnull/isnotnull null alamayan tipte sabit false/true döner (önceden ifade hatası).
  • RequestValidationBehavior: doğrulayıcılar ValidateAsync ile (sırayla) çalışır. Önceden MustAsync/CustomAsync kuralları AsyncValidatorInvokedSynchronouslyException fırlatıyordu.
  • EfRepositoryBase soft delete 1:1 kontrolü: yalnız unique FK dolu ve benzersiz indeks DeletedDate filtresi içermiyorsa engeller. Önceden FK boş olsa bile her 1:1 ilişkili kayıt silinemiyordu.
  • Paginate: Pages artık Count atandıktan sonra hesaplanıyor (önceden 0 → HasNext hep false); size<=0 ve büyük size değerlerinde taşma/sıfıra bölme yok.
  • CacheRemovingBehavior: CacheGroupKey dizisinin tüm elemanları siliniyor (önceden hep ilk eleman).
  • [KIRICI] ExceptionMiddleware / HttpExceptionHandler
    • AuthorizationException: kimliği doğrulanmış kullanıcıda 403, anonimde 401 (önceden hep 401 → 401'de oturumu kapatan istemciler yetkisiz işlemde kullanıcıyı sistemden atıyordu).
    • İşleyici istek başına oluşturulur (önceden paylaşılan örnek eşzamanlı hatalarda başka isteğin yanıtına yazabiliyordu). Yanıt başlamışsa istisna yeniden fırlatılır. İstemci hataları (4xx) Information, diğerleri Error seviyesinde loglanır.
    • AuthorizationProblemDetails(string detail, int status = 401).
  • Yerelleştirme: AcceptLocales boşsa (Accept-Language'siz istek, arka plan işi) varsayılan dile düşülür (önceden NoNullAllowedException). YAML dosyaları süreç boyunca bir kez ayrıştırılır; kaynak klasörleri bir kez taranır (önceden her istekte/her çeviride).
  • Güvenlik: parola hash karşılaştırması sabit zamanlı (CryptographicOperations.FixedTimeEquals); OTP doğrulaması RFC 6238 ağ gecikmesi penceresini (±1 adım) kabul eder.
  • [KIRICI] EnsureDbApplied: veritabanı yoksa da migrate eder (önceden CanConnect false ise sessizce atlıyordu).
  • [KIRICI] PerformanceBehavior: Stopwatch artık DI'dan alınmaz (singleton/transient paylaşımı süreleri bozuyordu); yapıcı yalnız ILogger alır.
  • ElasticSearch: GetSearchByField alan/değer filtresini uygular (önceden tüm dokümanlar dönüyordu); InsertManyAsync toplu yazma hatalarını raporlar; hata mesajı ServerError boşken NRE vermez; ElasticClient tek örnek.
  • Test projesi eklendi: tests/BulutBusiness.Core.Tests.

10.0.9

  • BREAKING CHANGE — Timestamp alanları DateTime → DateTimeOffset:
    • IEntityTimestamps / Entity<TId>: CreatedDate, UpdatedDate, DeletedDate
    • AccessToken.ExpirationDate, RefreshToken.ExpirationDate, RefreshToken.RevokedDate
    • EfRepositoryBase ve JwtHelper artık DateTime.Now / DateTime.UtcNow yerine DateTimeOffset.UtcNow kullanıyor; sunucu saat dilimi (TZ env) davranışı etkilemiyor
    • Gerekli aksiyon: tüketici projelerde Entity<TId>'den türeyen entity'lerin DB kolon tipleri (datetime2 → datetimeoffset) için yeni EF Core migration oluşturulmalı; DTO/mapping katmanlarında DateTime bekleyen kod DateTimeOffset'e güncellenmeli
  • Paket güncellemeleri (breaking change yok, API uyumlu):
    • AWSSDK.Translate 4.0.1.23 → 4.0.100.14
    • MailKit 4.16.0 → 4.18.0, MimeKit 4.16.0 → 4.18.1
    • MediatR 14.1.0 → 14.2.0
    • Microsoft.EntityFrameworkCore(.InMemory/.Relational) 10.0.5 → 10.0.12
    • Microsoft.IdentityModel.Tokens / System.IdentityModel.Tokens.Jwt 8.17.0 → 8.22.0 (8.23.0 bilinçli olarak atlandı — 2 gün önce yayınlandı, güvenlik-kritik bir bağımlılık için "olgunlaşmasını" beklemek adına bir önceki stabil sürüm tercih edildi)
    • Serilog 4.3.1 → 4.4.0
    • YamlDotNet 16.3.0 → 18.1.0
    • Not: Proje zaten MediatR 14.x kullanıyor; MediatR v13'ten itibaren üretim kullanımı için ticari lisans gerektiriyor (bkz. luckypennysoftware.com). Bu güncellemenin getirdiği yeni bir durum değil, ancak lisans durumunuzun kontrol edilmesi önerilir.

10.0.8

  • Güvenlik güncellemesi: MailKit 4.15.1 → 4.16.0, MimeKit 4.15.1 → 4.16.0
  • Breaking change yok — mevcut API kullanımı tam uyumlu

10.0.7

  • Yetki Grubu (RoleGroup) altyapısı eklendi
    • RoleGroup<TId> — Name, Description, IsActive alanlarıyla yetki grubu entity'si
    • RoleGroupOperationClaim<TId, TRoleGroupId, TOperationClaimId> — grup ↔ claim N:N köprüsü
    • UserRoleGroup<TId, TUserId, TRoleGroupId> — kullanıcı ↔ grup N:N köprüsü
  • ITokenHelper yeni overload — CreateToken(user, directClaims, roleGroups, roleGroupClaims): aktif grupların claim'lerini otomatik flatten + distinct ederek token'a yazar; geriye dönük uyumlu (eski imza korundu)
  • Navigation property'ler Core entity'lerine eklenmedi — bağımlılıkları sıfır tutar, uygulama katmanı kendi Domain entity'lerinde tanımlar

10.0.6

  • EfRepositoryBase: CreatedDate, UpdatedDate, DeletedDate timestamp'leri DateTime.UtcNow → DateTime.Now olarak değiştirildi. Container TZ ortam değişkeni ile yerel saat desteği sağlandı.
  • Paket güncellemeleri: FluentValidation 12.1.1, MailKit 4.15.1, MediatR 14.1.0, EF Core 10.0.5, Microsoft.IdentityModel.Tokens 8.17.0, Swashbuckle 10.1.7, Otp.NET 1.4.1, Serilog 4.3.1

10.0.5

  • .NET 10 desteği
  • MimeKit 4.14.1, EF Core 10.0.2

10.0.x (önceki)

  • .NET 9 → .NET 10 geçişi
  • JWT, Repository, CQRS pipeline altyapısı

Gereksinimler

  • .NET 10+
  • Entity Framework Core 10 uyumlu veritabanı (SQL Server, PostgreSQL vb.)
  • (Opsiyonel) ElasticSearch 7.x
  • (Opsiyonel) AWS hesabı (Amazon Translate için)
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
10.1.1 170 10/1/2026
10.1.0 109 9/30/2026
10.0.9 220 9/20/2026
10.0.8 851 4/19/2026
10.0.7 188 4/9/2026
10.0.6 254 4/5/2026
10.0.5 389 1/31/2026
10.0.4 149 1/31/2026
10.0.3 150 1/31/2026
10.0.2 147 1/31/2026
10.0.1 157 1/31/2026
10.0.0 189 11/29/2025
1.0.5 303 7/13/2025
1.0.4 503 6/9/2025
1.0.3 242 6/1/2025
1.0.2 301 4/22/2025
1.0.1 271 4/22/2025
1.0.0 246 4/21/2025