Ledbim.Core
1.1.2
See the version list below for details.
dotnet add package Ledbim.Core --version 1.1.2
NuGet\Install-Package Ledbim.Core -Version 1.1.2
<PackageReference Include="Ledbim.Core" Version="1.1.2" />
<PackageVersion Include="Ledbim.Core" Version="1.1.2" />
<PackageReference Include="Ledbim.Core" />
paket add Ledbim.Core --version 1.1.2
#r "nuget: Ledbim.Core, 1.1.2"
#:package Ledbim.Core@1.1.2
#addin nuget:?package=Ledbim.Core&version=1.1.2
#tool nuget:?package=Ledbim.Core&version=1.1.2
ProjectBase.Core — Kullanım Rehberi (ASP.NET Core 10 / Clean Architecture)
Bu doküman, ProjectBase.Core kütüphanesini hiç bilmeyen birinin kendi Api / Application / Domain / Infrastructure çözümüne güvenle entegre edebilmesi için hazırlandı.
ProjectBase.Core size şunları “tek yerden, tek standartla” sağlar:
- Result modeli (tek tip API response)
- BaseController (Result →
IActionResultçevirimi) - JWT + BasicAuth (tek “smart scheme” ile)
- OpenAPI (çoklu doküman + Scalar UI uyumlu security scheme’ler)
- Global error handling (middleware)
- HTTP request/response logging + correlation id (middleware)
- MediatR pipeline behaviors (logging/validation/performance/exception)
- EF Core için BaseContext (audit + soft delete)
- Generic repository + pagination/filter/sort yardımcıları
- Enum → localized message kataloğu (
ILocalizedMessages+ICultureCatalog) - FileService (IIS FTP üzerinden dosya yükleme/silme, otomatik klasör oluşturma)
Bu repo içinde ayrıca örnek bir çözüm de var (
Services/*). İsterseniz birebir aynı kurgu ile ilerleyebilirsiniz; amaProjectBase.Coretek başına da kullanılabilir.
Yeni özellik: Localized Messages (enum → metin)
Bu repo’da “handler içinde hard-coded text yazmak” yerine, mesajları enum anahtarları üzerinden kültüre göre çözümleyen bir altyapı var:
ILocalizedMessages:Get<TEnum>(TEnum key, params object[] args)ile mesajı döner.ICultureCatalog: Her kültür için, enum tiplerini mesaj sözlüklerine map’ler (enumType → (enumValue → text)).- Fallback kuralı:
- Aktif kültürde anahtar bulunamazsa default kültüre düşer (
tr-tr) - Orada da bulunamazsa
key.ToString()döner
- Aktif kültürde anahtar bulunamazsa default kültüre düşer (
DI (önerilen)
Application katmanında (repo örneği: Services/ProjectBase.Application/DependencyInjection.cs) aşağıdaki kayıtlar yapılır:
services.AddLocalizations();- Her kültür için birer
ICultureCatalogimplementasyonu:services.AddSingleton<ICultureCatalog, TrCatalog>();services.AddSingleton<ICultureCatalog, EnCatalog>();
Not:
AddLocalizations()içindeHttpContext’ten kültür okuyabilmek içinHttpContextAccessorda register edilir.
Handler’da kullanım örneği
Repo örneği (Services/ProjectBase.Application/Handlers/Users/UserCreateCommandHandler.cs) kullanıcı zaten varsa:
return Result.Fail(ResultType.Conflict, _localizedMessages.Get(UserMessages.UserAlreadyCreated));
Katalog yapısı (örnek)
TrCatalog/EnCatalog: Kültür bazlı “root map”CommonCatalog,UserCatalog: İlgili enum’a ait TR/EN mesaj sözlükleri
Hızlı Başlangıç (Core’u kendi projene ekle)
Ön Koşullar
- .NET SDK:
net10.0 - ASP.NET Core 10
- (EF kullanacaksanız) bir veritabanı sağlayıcısı (repo örneği: SQL Server)
1) Dosyaları/Projeleri çözümüne ekle
Bu repo’da ProjectBase.Core paketlerini ProjectBase.Packages üzerinden alıyor.
- Önerilen yöntem (Project Reference):
- Çözümünüze
ProjectBase.CoreveProjectBase.Packagesprojelerini ekleyin. - Root’taki
Directory.Build.propsdosyasını da çözüm köküne taşıyın/kopyalayın. (OpenAPI source generator interceptor namespace’i için)
- Çözümünüze
2) Referansları ver
Bu core’u “sarmal” (chain) referans yapısıyla kullanabilirsiniz. Önerilen Clean Architecture referans zinciri:
- Domain → Core
- Infrastructure → Domain
- Application → Infrastructure
- Api → Application
Bu sayede Api projesi Core’u doğrudan referanslamadan (transitive) Core tiplerine ulaşabilir.
Örnek csproj referansları:
<ItemGroup>
<ProjectReference Include="..\ProjectBase.Core\ProjectBase.Core.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ProjectBase.Domain\ProjectBase.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ProjectBase.Infrastructure\ProjectBase.Infrastructure.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ProjectBase.Application\ProjectBase.Application.csproj" />
</ItemGroup>
Not: Repo örneğinde API, bazı extension’ları doğrudan çağırdığı için (
ProjectBase.Core.Extensions) API projesi Core’u da referanslıyor. Siz zincir yapıyı tercih ediyorsanız, API’de çağırdığınız extension’ların Application (veya API’ye en yakın) katmanda “wrapper” metotlarla dışarı açılması daha temiz olur.
3) Program.cs minimum kurulum
Aşağıdaki akış, repo’daki gerçek kurulumla aynıdır:
using ProjectBase.Core.Extensions;
using Scalar.AspNetCore;
using Serilog;
Log.Logger = new LoggerConfiguration()
.ConfigureLogging()
.CreateLogger();
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog(Log.Logger);
var openApiDocuments = builder.Configuration.GetSection("OpenApi:Documents").Get<string[]>() ?? ["v1"];
builder.Services.AddControllers();
builder.Services.AddApiVersion();
builder.Services.AddJwtAuthentication(builder.Configuration);
builder.Services.AddOpenApi(builder.Configuration, openApiDocuments);
var app = builder.Build();
app.MapOpenApi("/openapi/{documentName}.json");
app.MapScalarApiReference(o => o.AddDocuments(openApiDocuments));
app.UseMiddlewares(); // HttpLogging + ExceptionHandling
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
4) Application katmanı için minimum DI (önerilen)
Bu core, MediatR pipeline ve HTTP logging option’larını da desteklediği için Application tarafında tipik kurulum şöyle olur (repo’da birebir örneği: Services/ProjectBase.Application/DependencyInjection.cs):
using FluentValidation;
using MediatR;
using ProjectBase.Core.Extensions;
using ProjectBase.Core.Logging.Models;
services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(DependencyInjection).Assembly));
services.AddValidatorsFromAssembly(typeof(DependencyInjection).Assembly);
services.Configure<HttpLoggingOptions>(configuration.GetSection("LoggingOptions"));
services.AddPipelineBehaviors();
Zorunlu / Opsiyonel Konfigürasyonlar (appsettings)
JWT (Zorunlu)
AddJwtAuthentication(...) çağrısı JWT section’ını zorunlu bekler.
{
"JWT": {
"Audience": "YourAudience",
"Issuer": "YourIssuer",
"AccessTokenExpiration": 60,
"RefreshTokenExpiration": 60,
"AccessTokenSecurityKey": "YOUR_ACCESS_KEY_32+_CHARS",
"RefreshTokenSecurityKey": "YOUR_REFRESH_KEY_32+_CHARS",
"ProviderKey": "Your.Auth"
}
}
BasicAuth (Opsiyonel)
Authorization: Basic ... geldiğinde otomatik Basic’e düşer. (Korumalı internal endpoint’ler için pratik.)
{
"BasicAuth": {
"User": { "Username": "admin", "Password": "secret" }
}
}
OpenAPI Documents (Opsiyonel)
Çoklu doküman istiyorsanız:
{ "OpenApi": { "Documents": [ "v1", "v2" ] } }
HTTP Logging Options (Opsiyonel ama önerilir)
HttpLoggingMiddleware davranışını LoggingOptions ile kontrol edersiniz. Repo’da binding örneği Services/ProjectBase.Application/DependencyInjection.cs içindedir.
Örnek:
{
"LoggingOptions": {
"enableRequestLogging": true,
"enableResponseLogging": true,
"maskSensitiveData": true,
"maxBodyLength": 65536,
"correlationHeaderName": "X-Correlation-Id",
"truncateRequestBody": true,
"maxRequestBodyBytes": 65536,
"maxResponseBodyBytes": 65536,
"responseLogLevel": "Information",
"errorLogLevel": "Error",
"sensitiveFieldMatchMode": "Contains",
"maskWith": "****",
"sensitiveFields": [ "password", "token", "authorization" ],
"excludePaths": [ "/openapi", "/health" ]
}
}
“Kullanman gereken” ana metotlar ve ne işe yararlar
BaseController.CreateActionResult(...)
Dosya: ProjectBase.Core/Api/Controllers/BaseController.cs
- Ne sağlar: Handler’dan dönen
Result/Result<T>’yi HTTP response’a çevirir. - Nasıl: HTTP status code’u
ResultTypeüzerinden set eder, body olarakresultdöner. - Kullanım: Controller’ı
BaseController’dan türetin vereturn CreateActionResult(await _mediator.Send(...));yazın.
Result.Success(...) / Result.Fail(...)
Dosyalar: ProjectBase.Core/Results/Result.cs, ProjectBase.Core/Results/Result {T}.cs
- Ne sağlar: Uygulama katmanında “başarılı/başarısız” standardı.
- Kritik kural:
Success(...)sadeceSuccess/Created/NoContentgibi success tipleriyle;Fail(...)ise failure tipleriyle çağrılabilir (aksi halde exception fırlatır).
services.AddApiVersion()
Dosya: ProjectBase.Core/Extensions/ApiVersionExtension.cs
- Ne sağlar: URL segment (
api/v1/...) + query (?version=1.0) + header (X-Version) + media-type param (ver) ile versioning. - OpenAPI entegrasyonu:
GroupNameFormat = "v1", "v2", ...gibi doküman gruplarını üretir.
services.AddJwtAuthentication(configuration)
Dosya: ProjectBase.Core/Extensions/JwtAuthenticationExtension.cs
- Ne sağlar: Tek bir policy scheme (
JWT_OR_BASIC) ile:- Header
Basic ...ise BasicAuth - Değilse JWT Bearer
- Header
- JWT üretimi:
JwtTokenGenerator+IJwtTokenGeneratorDI’a eklenir. - Standart hata body: 401/403 durumlarında
Resultformatında JSON döner.
services.AddOpenApi(configuration, documents)
Dosya: ProjectBase.Core/Extensions/OpenApiExtension.cs
- Ne sağlar: Doküman bazlı OpenAPI kaydı (ör.
v1,v2) ve Scalar UI için Bearer + Basic security scheme tanımı. - Not: Dokümana global security requirement ekler; anonymous endpoint’leriniz için action bazında
[AllowAnonymous]kullanabilirsiniz.
Convention-based endpoint docs (Summary/Description otomatik doldurma)
AddOpenApi(...) içinde bir OperationTransformer vardır: Eğer bir action için operation.Summary / operation.Description değerleri explicit olarak verilmediyse, bunları isim konvansiyonu ile bir “docs” sınıfından okumayı dener.
- Controller namespace → Docs namespace:
ProjectBase.Api.Controllers.v1→ProjectBase.Api.OpenApiDocs.v1
- Docs type candidate’ları (sırayla dener):
{DocsNamespace}.{ControllerName}s.{ControllerName}OpenApiDocs(önerilen, plural folder){DocsNamespace}.{ControllerName}.{ControllerName}OpenApiDocs(singular folder){DocsNamespace}.{ControllerName}OpenApiDocs(no folder)
- Nested type:
{ActionName} - Alanlar:
public const string Summary,public const string Description
Örnek (repo içindeki gerçek dosya):
// Services/ProjectBase.Api/OpenApiDocs/v1/Users/UserOpenApiDocs.cs
namespace ProjectBase.Api.OpenApiDocs.v1.Users;
public static class UserOpenApiDocs
{
public static class Register
{
public const string Summary = "Kullanıcı oluşturma işlemi";
public const string Description = """
JWT Bearer token gerektirir.
- **Name** (`string`): zorunlu, en fazla 64 karakter
- **Surname** (`string`): zorunlu, en fazla 64 karakter
- **Mail** (`string`): zorunlu, en fazla 64 karakter, geçerli e-posta formatı
- **Password** (`string`): zorunlu, en az 8 karakter
""";
}
}
Not: Bu mekanizma, action üzerinde Summary/Description zaten verilmişse override etmez; sadece boş olan alanları doldurur.
app.UseMiddlewares()
Dosya: ProjectBase.Core/Extensions/MiddlewareExtension.cs
- Sıra:
HttpLoggingMiddleware: request/response body (uygunsa) loglar, correlation id üretir/taşır.ExceptionHandlingMiddleware: exception’ları yakalar ve JSONResultdöner.
services.AddPipelineBehaviors() (MediatR)
Dosya: ProjectBase.Core/Extensions/PipelineBehaviorExtension.cs
- Ne sağlar: Handler’larınızda tekrar eden cross-cutting işleri otomatikleştirir:
LoggingBehaviour<,>ValidationBehaviour<,>(FluentValidation)PerformanceBehaviour<,>UnhandledExceptionBehaviour<,>
new LoggerConfiguration().ConfigureLogging() (Serilog)
Dosya: ProjectBase.Core/Extensions/ConfigureLoggingExtension.cs
- Ne sağlar: Console + Seq sink’leri ve temel filtreler.
- Not: Seq URL’i şu an sabit:
http://localhost:5341(isterseniz extension içinde config’e bağlayarak geliştirebilirsiniz).
EF Core: Audit + Soft Delete kullanımı
BaseContext
Dosya: ProjectBase.Core/Data/Contexts/BaseContext.cs
- Audit:
Created*/Updated*alanlarınıSaveChangesAsyncsırasında otomatik doldurur. - Soft delete:
Remove(...)çağrısında entityIHardDeletedeğilse fiziksel silmez,IsDeleted=trueyapar. - Current user:
HttpContext.Userclaim’lerindenUserName→ClaimTypes.Name→ClaimTypes.NameIdentifiersırasıyla okur.
BaseEntity / BaseEntity<TKey>
Dosya: ProjectBase.Core/Entities/BaseEntity.cs
- Ne sağlar: Audit alanları +
IsDeleted+ (generic tipte)Id.
Repository: Core’un sunduğu yüzey (CRUD + paging)
IRepository<T>
Dosya: ProjectBase.Core/Repositories/EfCore/IRepository.cs
- Add:
AddAsync,AddRangeAsync - Update:
UpdateAsync,UpdateRangeAsync,UpdateAsync(predicate, setPropertyCalls)(bulk) - Delete:
DeleteAsync(entity),DeleteAsync(predicate),DeleteRangeAsync - Get:
GetAsync,GetAllAsync,GetAllPagedAsync,GetCountAsync
Repository<T>
Dosya: ProjectBase.Core/Repositories/EfCore/Repository {T}.cs
- Ne sağlar: EF Core
DbSet<T>üzerinden generic implementasyon. - Okuma:
AsNoTracking()kullanır. - Paging:
CountAsync+Skip/Take.
Bulk Update (UpdateAsync predicate + setPropertyCalls)
UpdateAsync(entity) ve UpdateRangeAsync(entities) change tracker üzerinden çalışır; SaveChangesAsync sırasında audit alanları (UpdatedDate, UpdatedBy) otomatik doldurulur. Bulk update senaryosunda ise EF Core ExecuteUpdateAsync kullanılır; bu metot change tracker’ı atladığı için audit alanları normal akışta güncellenmez.
Core’daki UpdateAsync(Expression<Func<T, bool>> predicate, Action<UpdateSettersBuilder<T>> setPropertyCalls) overload’u bu durumu çözer:
- Ne yapar:
ExecuteUpdateAsyncile predicate’e uyan tüm satırları tek sorguda günceller. - Audit:
UpdatedDateveUpdatedByotomatik eklenir (BaseContext.GetCurrentUser()ile;SaveChangesAsyncile aynı mantık). - Dönüş:
Result<int>— güncellenen satır sayısı.
Kullanım örneği:
// Tek property güncelleme
var result = await _repository.UpdateAsync(
x => x.CategoryId == categoryId,
s => s.SetProperty(e => e.IsProcessed, true));
// Birden fazla property
var result = await _repository.UpdateAsync(
x => x.Status == "Pending",
s =>
{
s.SetProperty(e => e.Status, "Active");
s.SetProperty(e => e.ProcessedAt, DateTime.Now);
});
if (result.IsSuccess)
var updatedCount = result.Data; // Güncellenen satır sayısı
Not:
UpdateSettersBuilder<T>EF Core 10 API’sine aittir.UpdatedDateveUpdatedByher çağrıda otomatik set edilir; kullanıcınınsetPropertyCallsiçinde bu alanları vermesi gerekmez.
Dapper: Handler içinde hızlı SQL (opsiyonel)
Bu repo’da Dapper entegrasyonu, “EF repository desenini bozmadan” handler içinde gerektiğinde ham SQL çalıştırabilmeniz için tasarlandı.
IDapperExecutor
Dosya: ProjectBase.Core/Repositories/Dapper/IDapperExecutor.cs
- Ne sağlar: Handler’a inject edip
QueryAsync<T> / QuerySingleOrDefaultAsync<T> / ExecuteAsyncile Dapper sorgusu çalıştırmanızı sağlar.
IDbConnectionProvider + EfCoreDbConnectionProvider<TContext>
Dosyalar:
ProjectBase.Core/Repositories/Dapper/IDbConnectionProvider.csProjectBase.Core/Repositories/Dapper/EfCoreDbConnectionProvider.csNe sağlar: Dapper’ın kullanacağı
DbConnectionve (varsa)DbTransactionbilgisini verir.Kritik özellik: EF Core ile
BeginTransactionAsync()açıldıysa, Dapper da aynı connection/transaction üzerinde çalışır. (TekCommit/Rollbackile yönetim.)
DI kaydı
Dosya: ProjectBase.Core/Repositories/DependencyInjection.cs
Repo örneğinde, Infrastructure katmanında DbContext kurulumundan sonra şöyle bağlanır:
services.AddRepositories<ApplicationContext>(); // Dapper: IDbConnectionProvider + IDapperExecutor
Not:
AddRepositories<TContext>generic olduğu için kendi context’inizi verirsiniz (ör.MyAppContext).
Handler’da kullanım örneği (transaction ile)
Transaction gerekiyorsa standardınız IUnitOfWork olduğu için, sadece Dapper çalıştıracak olsanız bile transaction’ı UoW ile açıp yönetebilirsiniz:
await uow.BeginTransactionAsync();
try
{
var r = await dapper.ExecuteAsync("UPDATE Users SET Name=@Name WHERE Id=@Id", new { Id = userId, Name = "X" }, cancellationToken: ct);
if (!r.IsSuccess) { await uow.RollbackAsync(); return Result.Fail(ResultType.InternalServerError, "Dapper failed"); }
await uow.CommitAsync();
return Result.Success(ResultType.Success, "OK");
}
catch
{
await uow.RollbackAsync();
return Result.Fail(ResultType.InternalServerError, "Transaction failed");
}
Not: Transaction açmazsanız Dapper komutları transaction’sız çalışır (SQL Server’da statement bazında atomik; ama “birden fazla statement tek commit/rollback” olmaz).
MongoDB: NoSQL altyapısı (ortak kullanım)
Ledbim.Core, MongoDB kullanımı için hazır altyapı sağlar. EF Core repository desenine benzer şekilde IMongoRepository<T> ile çalışır.
MongoBaseEntity / MongoBaseEntityWithObjectId / MongoBaseEntity<TKey>
Dosya: Ledbim.Core/Entities/Mongo/MongoBaseEntity.cs - Audit alanları ve soft delete içerir.
IMongoRepository<T>
Dosya: Ledbim.Core/Repositories/Mongo/IMongoRepository.cs - AddAsync, UpdateAsync, DeleteAsync, GetAsync, GetAllPagedAsync vb.
DI kaydı
appsettings.json: "MongoDb": { "ConnectionString": "mongodb://localhost:27017", "DatabaseName": "LedbimDb" }
Program.cs: builder.Services.AddMongoDb(builder.Configuration); builder.Services.AddMongoRepository<MyDocument>();
HTTP: Dış servislere ortak client (Result<T> dönen)
Handler içinde her seferinde HttpClient inject edip serialize / deserialize / error-handling yazmak yerine, Core’da hazır bir wrapper var:
IHttpResultClient(Dosya:ProjectBase.Core/Http/IHttpResultClient.cs)HttpResultClient(partial sınıf):ProjectBase.Core/Http/HttpResultClient.cs(ctor + kısa public API)ProjectBase.Core/Http/HttpResultClient.Send.cs(çekirdek send/response akışı)ProjectBase.Core/Http/HttpResultClient.FormData.cs(multipart/form-data upload)ProjectBase.Core/Http/HttpResultClient.Helpers.cs(helper’lar + private tipler)
DI
Infrastructure içinde otomatik eklenir:
services.AddHttpResultClient();
Not: Dış servis için named client tanımlamanız önerilir.
Named HttpClient örneği
API projesinde (örn. Services/ProjectBase.Api/Program.cs) config’ten base address verip named client ekleyebilirsiniz:
builder.Services.AddHttpClient("UserService", c =>
{
c.BaseAddress = new Uri(builder.Configuration["Integrations:UserService:BaseUrl"]!);
});
Handler’da kullanım örneği
public sealed class UsersQueryHandler(IHttpResultClient http) : IRequestHandler<UsersQuery, Result<List<UserDto>>>
{
public async Task<Result<List<UserDto>>> Handle(UsersQuery request, CancellationToken ct)
{
return await http.GetAsync<List<UserDto>>(
clientName: "UserService",
// NOTE: Leading '/' resets BaseAddress path. Prefer relative paths (no leading slash).
url: "api/users",
cancellationToken: ct);
}
}
POST multipart/form-data (Form + File upload)
Dosya upload gibi senaryolar için:
- Metot:
PostFormDataAsync<TResponse>(...) - Dosya parçası modeli:
FormFilePart(Dosya:ProjectBase.Core/Http/FormFilePart.cs)
Örnek kullanım:
var fields = new Dictionary<string, string?>
{
["name"] = "Altin",
["age"] = "30"
};
await using var fs = File.OpenRead("c:\\temp\\photo.jpg");
var files = new[]
{
new FormFilePart(
Name: "file", // server tarafında beklenen field adı
Content: fs, // stream (file/network/memory)
FileName: "photo.jpg", // request'teki filename
ContentType: "image/jpeg", // opsiyonel
LeaveOpen: true) // true: stream kapatma sorumluluğu sende
};
var result = await http.PostFormDataAsync<MyResponse>(
clientName: "UserService",
url: "api/users/upload",
fields: fields,
files: files,
cancellationToken: ct);
Not:
LeaveOpen=false(default) ise istek tamamlanınca stream dispose edilir (en güvenli varsayılan).LeaveOpen=trueise stream açık kalır; işin bitince sen dispose etmelisin.
FileService: IIS FTP üzerinden dosya yükleme / silme
IIS FTP sunucusuna dosya yüklemek ve silmek için IFileService kullanılır. FluentFTP kütüphanesi ile FTP protokolü üzerinden çalışır (obsolete FtpWebRequest yerine).
IFileService
Dosya: ProjectBase.Core/FileService/Interfaces/IFileService.cs
UploadAsync(FileUploadRequest, CancellationToken):IFormFileile dosya yükler. Klasör yolu yoksa otomatik oluşturur.UploadBase64Async(Base64UploadRequest, CancellationToken): Base64 içerikten dosya yükler.RemoveAsync(string pathOrUrl, CancellationToken): Verilen path/URL’deki dosyayı siler.
Modeller
FileUploadRequest:File(IFormFile),Folder(örn."Fairs/Test1/Test2/Test3")Base64UploadRequest:Base64Content,Folder,Extension(opsiyonel)FileUploadResult:Path(public CDN URL),Extension,SizeBytes
Konfigürasyon (appsettings.json)
{
"FtpSettings": {
"FtpAddress": "cdn.example.com",
"Username": "ftp_user",
"Password": "ftp_password"
}
}
- FtpAddress: IIS FTP host (örn.
cdn.example.comveyaftp://cdn.example.com). DönenPathiçinhttps://{host}/...kullanılır.
DI
Application katmanında (DependencyInjection.cs):
services.AddFileService(configuration);
Kullanım örneği
// IFormFile ile yükleme
var request = new FileUploadRequest
{
File = formFile,
Folder = "Fairs/Test1/Test2/Test3"
};
var result = await _fileService.UploadAsync(request, cancellationToken);
// result.Path = "https://cdn.example.com/Fairs/Test1/Test2/Test3/{guid}.ext"
// Silme
await _fileService.RemoveAsync(result.Path, cancellationToken);
Not:
Folderiçindeki klasör yapısı (örn.Fairs/Test1/Test2/Test3) yoksa, yüklemeden önce otomatik oluşturulur.
Pagination / Filter / Sort (liste ekranları için)
Core içinde liste ekranlarını standartlaştırmak için hazır modeller ve yardımcılar var:
- İstek modelleri:
ProjectBase.Core/Pagination/*PaginationFilterQuery(page/filter/sort DTO)PagedFilterRequest<T>(repository’ye giden hazır istek)
- Sonuç modelleri:
PagedModel<T>(repository’nin döndürdüğü ham veri + total)PagedResponse<T>vePagedHelper(API response formatına çevirme)
- Helper’lar:
ProjectBase.Core/Helpers/*FilterQueryHelper(filter’ıExpression<Func<T,bool>>predicate’e çevirme)SortQueryHelper(sort listesiniOrderBy/ThenByzincirine çevirme)
Pratik kullanım kuralı:
- Client’tan gelen alan isimlerini doğrudan entity alanlarına bağlamayın. Handler içinde bir allow-list / fieldMap oluşturup sadece izinli alanları filtre/sort’a açın.
Helpers: EnumHelper (Display/Parse/Convert)
Core içinde ProjectBase.Core/Helpers/EnumHelper.cs altında, enum’larla çalışmayı kolaylaştıran genel metotlar var:
- DisplayAttribute okuma:
GetDisplayName(...)GetDisplayShortName(...)GetDisplayDescription(...)
- Genel attribute okuma:
GetAttribute<TEnum, TAttribute>(...) - Liste üretme (UI/dropdown):
GetValues<TEnum>(),GetNames<TEnum>()GetDisplayItems<TEnum>()→(Value, DisplayName)listesi
- Parse/validate:
TryParse<TEnum>(...)TryParseDefined<TEnum>(...)IsDefined(...)
- Sayısal dönüşüm:
ToInt32(...),ToInt64(...)
Not:
EnumHelper,DisplayAttributegibi reflection tabanlı okumalarda tekrar maliyetini azaltmak için küçük bir cache kullanır.
Migrations (örnek akış)
Bu repo’da Infrastructure altında hazır komut dosyaları var:
Services/ProjectBase.Infrastructure/_01-migrations.cmd: migration ekler (startup project: API)Services/ProjectBase.Infrastructure/_02-update-database.cmd: database updateServices/ProjectBase.Infrastructure/_03-migrations-remove.cmd: son migration’ı siler
Kendi projenizde aynı yaklaşımı kullanacaksanız, startup project ve context adını kendi isimlerinize göre güncelleyin.
Sık Sorulan Sorular / Sorun Giderme
401 dönüyor ama neden?
JWTsection yok/eksik olabilir (AddJwtAuthentication bunu zorunlu bekler).- Token
Issuer/Audience/Keyuyumsuz olabilir. [Authorize]endpoint’ine token’sız istek atılıyor olabilir.
Soft delete istemiyorum, fiziksel silsin
- Entity’nize
IHardDeletemarker interface’ini ekleyin. (Dosya:ProjectBase.Core/Entities/EntityInterfaces.cs)
OpenAPI dokümanımda Bearer/Basic çıkmıyor
services.AddOpenApi(..., documents)çağrısını yaptığınızdan emin olun.MapOpenApi("/openapi/{documentName}.json")route’unu map’leyin.- Scalar UI için
MapScalarApiReference(...)ile dokümanları ekleyin.
| 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
- Asp.Versioning.Mvc (>= 8.1.0)
- Asp.Versioning.Mvc.ApiExplorer (>= 8.1.0)
- Dapper (>= 2.1.66)
- FluentFTP (>= 52.1.0)
- FluentValidation (>= 12.1.1)
- FluentValidation.DependencyInjectionExtensions (>= 12.1.1)
- MassTransit.RabbitMQ (>= 8.4.1)
- MediatR (>= 14.0.0)
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 10.0.1)
- Microsoft.AspNetCore.OpenApi (>= 10.0.1)
- Microsoft.EntityFrameworkCore.SqlServer (>= 10.0.1)
- Microsoft.OpenApi (>= 2.3.0)
- MongoDB.Driver (>= 3.6.0)
- Scalar.AspNetCore (>= 2.11.9)
- Serilog.AspNetCore (>= 9.0.0)
- Serilog.Sinks.Elasticsearch (>= 9.0.3)
- Serilog.Sinks.Seq (>= 9.0.0)
NuGet packages (7)
Showing the top 5 NuGet packages that depend on Ledbim.Core:
| Package | Downloads |
|---|---|
|
Ledbim.Messaging
MassTransit/RabbitMQ entegrasyonu. IIntegrationEventBus arayüzünün transport-agnostic implementasyonu, consumer logging filtresi ve correlation ID altyapısı içerir. Ledbim.Core üzerine inşa edilmiştir. |
|
|
Ledbim.Security
JWT ve BasicAuth hybrid kimlik doğrulama, refresh token rotation ve hırsızlık tespiti, AES-256-GCM şifreleme ve PBKDF2-SHA512 parola hashing altyapısı. Ledbim.Core üzerine inşa edilmiştir. |
|
|
Ledbim.EntityFramework
Entity Framework Core ve Dapper tabanlı veri erişim altyapısı. BaseContext (audit, soft delete, domain event toplama), generic Repository, ITransactionManager, Dapper executor ve dinamik LINQ sorgu desteği içerir. Ledbim.Core üzerine inşa edilmiştir. |
|
|
Ledbim.AspNetCore
ASP.NET Core entegrasyonu: middleware, Serilog yapılandırması, API versioning, OpenAPI/Scalar, localization ve MediatR pipeline behavior kayıtları içerir. Ledbim.Core üzerine inşa edilmiştir. |
|
|
Ledbim.Http
Typed HTTP client wrapper. IHttpClientFactory tabanlı, Result pattern dönen IHttpResultClient implementasyonu içerir. GET, POST JSON, POST multipart form data ve generic send desteği sunar. Ledbim.Core üzerine inşa edilmiştir. |
GitHub repositories
This package is not used by any popular GitHub repositories.