Levge.Domain
2.3.0
dotnet add package Levge.Domain --version 2.3.0
NuGet\Install-Package Levge.Domain -Version 2.3.0
<PackageReference Include="Levge.Domain" Version="2.3.0" />
<PackageVersion Include="Levge.Domain" Version="2.3.0" />
<PackageReference Include="Levge.Domain" />
paket add Levge.Domain --version 2.3.0
#r "nuget: Levge.Domain, 2.3.0"
#:package Levge.Domain@2.3.0
#addin nuget:?package=Levge.Domain&version=2.3.0
#tool nuget:?package=Levge.Domain&version=2.3.0
Levge.Domain
SaaS ve bireysel API projelerinde domain katmanı altyapısı olarak kullanılmak üzere tasarlanmış NuGet paketidir. Entity hiyerarşisi, domain event sistemi, Result pattern ve ortak enum/interface'leri içerir.
Kurulum
dotnet add package Levge.Domain
İçerik
| Katman | Sınıf / Interface | Açıklama |
|---|---|---|
| Entities | EntityBase |
Tüm entity'lerin temel sınıfı (long Id + domain events) |
| Entities | AuditableEntity |
Oluşturma, güncelleme, soft delete takibi |
| Entities | FullAuditableEntity |
AuditableEntity + IsActive |
| Entities | TenantEntity |
AuditableEntity + TenantId |
| Entities | FullAuditableTenantEntity |
FullAuditableEntity + TenantId |
| Interfaces | IEntity |
long Id sözleşmesi |
| Interfaces | IAuditable |
Oluşturma/güncelleme audit sözleşmesi |
| Interfaces | ISoftDeletable |
Soft delete sözleşmesi |
| Interfaces | IActivatable |
IsActive sözleşmesi |
| Interfaces | IFullAuditable |
IAuditable + ISoftDeletable + IActivatable |
| Interfaces | ITenantEntity |
Multi-tenant TenantId sözleşmesi |
| Interfaces | IHasDomainEvents |
Domain event yayımlama sözleşmesi |
| Events | IDomainEvent |
Tüm domain event'leri için temel interface |
| Events | DomainEvent |
Otomatik Id ve OccurredOnUtc içeren soyut record |
| Events | IDomainEventHandler<T> |
Event handler sözleşmesi |
| Events | IDomainEventDispatcher |
Event dispatcher sözleşmesi |
| Primitives | Error |
Code + Message taşıyan değer nesnesi |
| Primitives | Result / Result<T> |
Exception fırlatmadan hata iletimi |
| Enums | AppUserRole |
SuperAdmin, Admin, Moderator, User, Guest |
| Enums | AuditAction |
Created, Updated, Deleted, Restored, Activated, Deactivated, Login, Logout |
Entity Kullanımı
Temel Entity
public class Product : AuditableEntity
{
public string Name { get; private set; }
public decimal Price { get; private set; }
private Product() { }
public static Product Create(string name, decimal price, long createdByUserId)
{
return new Product
{
Name = name,
Price = price,
CreatedAt = DateTime.UtcNow,
CreatedByUserId = createdByUserId
};
}
}
Multi-Tenant Entity
public class Invoice : FullAuditableTenantEntity
{
public string Number { get; private set; }
public decimal Total { get; private set; }
private Invoice() { }
public static Invoice Create(string number, decimal total, long tenantId, long createdByUserId)
{
return new Invoice
{
Number = number,
Total = total,
TenantId = tenantId,
CreatedAt = DateTime.UtcNow,
CreatedByUserId = createdByUserId,
IsActive = true
};
}
}
Domain Event Kullanımı
1. Event Tanımla
// Events/OrderCreatedEvent.cs
public sealed record OrderCreatedEvent(long OrderId, long CustomerId, decimal Total) : DomainEvent;
// Events/OrderCancelledEvent.cs
public sealed record OrderCancelledEvent(long OrderId, string Reason) : DomainEvent;
2. Entity'de Event Yayımla
public class Order : FullAuditableEntity
{
public long CustomerId { get; private set; }
public decimal Total { get; private set; }
public string Status { get; private set; } = "Pending";
private Order() { }
public static Order Create(long customerId, decimal total, long createdByUserId)
{
var order = new Order
{
CustomerId = customerId,
Total = total,
CreatedAt = DateTime.UtcNow,
CreatedByUserId = createdByUserId,
IsActive = true
};
order.RaiseDomainEvent(new OrderCreatedEvent(order.Id, customerId, total));
return order;
}
public void Cancel(string reason, long updatedByUserId)
{
Status = "Cancelled";
UpdatedAt = DateTime.UtcNow;
UpdatedByUserId = updatedByUserId;
RaiseDomainEvent(new OrderCancelledEvent(Id, reason));
}
}
3. Handler Yaz (Application katmanı)
public class OrderCreatedEventHandler : IDomainEventHandler<OrderCreatedEvent>
{
private readonly IEmailService _emailService;
public OrderCreatedEventHandler(IEmailService emailService)
{
_emailService = emailService;
}
public async Task HandleAsync(OrderCreatedEvent domainEvent, CancellationToken cancellationToken = default)
{
await _emailService.SendOrderConfirmationAsync(domainEvent.CustomerId, domainEvent.OrderId);
}
}
4. Dispatcher Implemente Et (Infrastructure katmanı)
public class DomainEventDispatcher : IDomainEventDispatcher
{
private readonly IServiceProvider _serviceProvider;
public DomainEventDispatcher(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public async Task DispatchAsync(IDomainEvent domainEvent, CancellationToken cancellationToken = default)
{
var handlerType = typeof(IDomainEventHandler<>).MakeGenericType(domainEvent.GetType());
var handlers = _serviceProvider.GetServices(handlerType);
foreach (var handler in handlers)
{
await ((dynamic)handler).HandleAsync((dynamic)domainEvent, cancellationToken);
}
}
public async Task DispatchAsync(IEnumerable<IDomainEvent> domainEvents, CancellationToken cancellationToken = default)
{
foreach (var domainEvent in domainEvents)
await DispatchAsync(domainEvent, cancellationToken);
}
}
5. SaveChanges Sonrası Dispatch Et (EF Core)
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
var result = await base.SaveChangesAsync(cancellationToken);
var entities = ChangeTracker.Entries<IHasDomainEvents>()
.Select(e => e.Entity)
.Where(e => e.DomainEvents.Any())
.ToList();
foreach (var entity in entities)
{
await _dispatcher.DispatchAsync(entity.DomainEvents, cancellationToken);
entity.ClearDomainEvents();
}
return result;
}
Result Pattern Kullanımı
Service Katmanında
public async Task<Result<UserDto>> GetUserAsync(long id)
{
var user = await _repository.FindAsync(id);
if (user is null)
return Result.Failure<UserDto>(Error.NotFound);
return Result.Success(new UserDto(user.Id, user.Email));
}
Controller'da
[HttpGet("{id}")]
public async Task<IActionResult> Get(long id)
{
var result = await _userService.GetUserAsync(id);
if (result.IsFailure)
return NotFound(new { error = result.Error.Message });
return Ok(result.Value);
}
Özel Error Tanımlama
public static class UserErrors
{
public static readonly Error NotFound = Error.Create("User.NotFound", "Kullanıcı bulunamadı.");
public static readonly Error EmailAlreadyExists = Error.Create("User.EmailAlreadyExists", "Bu e-posta adresi zaten kullanımda.");
public static readonly Error InvalidCredentials = Error.Create("User.InvalidCredentials", "E-posta veya şifre hatalı.");
}
// Kullanım
return Result.Failure<UserDto>(UserErrors.EmailAlreadyExists);
Lisans
MIT © Serdar ÖZKAN
| Product | Versions 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. |
-
net10.0
- Levge.Exceptions (>= 2.3.0)
NuGet packages (6)
Showing the top 5 NuGet packages that depend on Levge.Domain:
| Package | Downloads |
|---|---|
|
Levge.Identity
Identity and authentication services for .NET applications. |
|
|
Levge.ConsistentResponse
A library for standardizing API responses in ASP.NET Core applications with consistent formatting, error handling, and exception middleware. |
|
|
Levge.MediatR
MediatR tabanlı domain event dispatcher, EF Core interceptor ve FluentValidation pipeline behavior. IDomainEventDispatcher implementasyonu, SaveChanges sonrası otomatik domain event dispatch ve ValidationBehavior altyapısı. |
|
|
Levge.Subscription
Levge ekosistemi için opsiyonel abonelik ve kota takip altyapısı. Plan, modül, tenant aboneliği, kullanım takibi ve yenileme job desteği. AddLevgeSubscription() ile projeye eklenebilir. |
|
|
Levge.Payment
Levge ekosistemi için opsiyonel ödeme altyapısı. Stripe ve Iyzico provider desteği, webhook işleme ve ödeme geçmişi. AddLevgePayment() ile projeye eklenebilir. |
GitHub repositories
This package is not used by any popular GitHub repositories.