ABP Framework ile Ad?m Ad?m Yaz?l?m Geli?tirme ? B?l?m 5: Application Layer Geli?tirme
Application Layer (Uygulama Katman?), uygulaman?n kullan?m senaryolar?n? (use cases) ve kullan?c? hikayelerini y?netir. Domain katman?ndaki i?levleri kullanarak kullan?c? aray?z?nden gelen isteklere yan?t verir ve sunum katman? ile domain katman? aras?ndaki bir k?pr? g?revi g?r?r. Bu b?l?mde, uygulama katman?n?n temel bile?enlerini ve geli?tirme pratiklerini ele alaca??z.
Application Service’ler Olu?turma
Application Service (Uygulama Servisi), d?? d?nyadan (UI, API) gelen isteklere do?rudan yan?t veren bir s?n?ft?r. Genellikle bir senaryoyu (?rn. “Yeni Kitap Olu?tur”, “Kitap Listesini Getir”) veya bir CRUD (Create, Read, Update, Delete) i?lemini temsil eder. Uygulama servisleri, domain katman?ndaki entity’leri ve domain servislerini kullanarak i? mant???n? koordine eder.
ABP’de bir uygulama servisi olu?turmak i?in Volo.Abp.Application.Services.ApplicationService s?n?f?ndan t?retilir:
C#
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using MyProject.Books;
using MyProject.Application.Contracts.Books; // DTO'lar burada tan?mlan?r
namespace MyProject.Application.Services
{
public class BookAppService : ApplicationService, IBookAppService
{
private readonly IRepository<Book, Guid> _bookRepository;
private readonly BookManager _bookManager; // Domain servislerini de enjekte edebiliriz
public BookAppService(IRepository<Book, Guid> bookRepository, BookManager bookManager)
{
_bookRepository = bookRepository;
_bookManager = bookManager;
}
public async Task<BookDto> GetAsync(Guid id)
{
var book = await _bookRepository.GetAsync(id);
return ObjectMapper.Map<Book, BookDto>(book); // AutoMapper kullan?m?
}
public async Task<List<BookDto>> GetListAsync()
{
var books = await _bookRepository.GetListAsync();
return ObjectMapper.Map<List<Book>, List<BookDto>>(books);
}
public async Task<BookDto> CreateAsync(CreateUpdateBookDto input)
{
var book = await _bookManager.CreateBookAsync(
input.Name,
input.Type,
input.PublishDate,
input.Price
);
return ObjectMapper.Map<Book, BookDto>(book);
}
public async Task UpdateAsync(Guid id, CreateUpdateBookDto input)
{
var book = await _bookRepository.GetAsync(id);
// G?ncelleme mant??? (Domain Service veya direkt entity ?zerinde)
await _bookRepository.UpdateAsync(book);
}
public async Task DeleteAsync(Guid id)
{
await _bookRepository.DeleteAsync(id);
}
}
}
ApplicationServices?n?f?, temel ?zellikler (?rn.ObjectMapper(AutoMapper),Logger,CurrentUser) ve ba??ml?l?k enjeksiyonu i?in kolayl?klar sa?lar.- Uygulama servisleri
IApplicationServicearay?z?n? implemente etmelidir. Bu, ABP’nin otomatik API denetleyicileri gibi ?zelliklerini kullanmak i?in ?nemlidir.
DTO (Data Transfer Object) Tasar?m?
DTO (Data Transfer Object), uygulama katman? ile sunum katman? aras?nda veri ta??mak i?in kullan?lan basit veri yap?s? s?n?flar?d?r. DTO’lar, entity’leri do?rudan if?a etmekten ka??n?r ve istemciye sadece ihtiya? duydu?u veriyi sunar.
BookDto: Bir kitap bilgilerini istemciye sunmak i?in.CreateUpdateBookDto: Yeni bir kitap olu?turmak veya mevcut bir kitab? g?ncellemek i?in istemciden gelen verileri almak i?in.
BookDto.cs (MyProject.Application.Contracts projesinde):
C#
using System;
using Volo.Abp.Application.Dtos;
namespace MyProject.Application.Contracts.Books
{
public class BookDto : AuditedEntityDto<Guid> // Audited bilgileri de i?erir
{
public string Name { get; set; }
public BookType Type { get; set; }
public DateTime PublishDate { get; set; }
public float Price { get; set; }
}
}
CreateUpdateBookDto.cs (MyProject.Application.Contracts projesinde):
C#
using System;
using System.ComponentModel.DataAnnotations;
namespace MyProject.Application.Contracts.Books
{
public class CreateUpdateBookDto
{
[Required]
[StringLength(128)]
public string Name { get; set; }
public BookType Type { get; set; } = BookType.Undefined; // Varsay?lan de?er
[Required]
public DateTime PublishDate { get; set; }
[Range(0, float.MaxValue)]
public float Price { get; set; }
}
}
- DTO’lar, UI katman?na ba?l? olarak ek do?rulama (validation) nitelikleri i?erebilir (
[Required],[StringLength],[Range]).
CRUD Operasyonlar? Implementasyonu
Uygulama servisleri genellikle entity’ler ?zerinde temel CRUD operasyonlar?n? implemente eder. ABP’nin IRepository aray?z? ve AutoMapper entegrasyonu sayesinde bu operasyonlar olduk?a basittir.
GetAsync: Tek bir entity’yi ID’sine g?re getirir ve DTO’ya d?n??t?r?r.GetListAsync: Entity listesini getirir ve DTO listesine d?n??t?r?r.CreateAsync: Bir DTO al?r, entity’ye d?n??t?r?r, kaydeder ve yeni entity’yi DTO olarak geri d?nd?r?r.UpdateAsync: Bir DTO al?r, mevcut entity’yi g?nceller ve g?ncellenmi? entity’yi DTO olarak geri d?nd?r?r.DeleteAsync: Bir entity’yi ID’sine g?re siler.
AutoMapper Profilleri ile Entity-DTO D?n???mleri
ABP, AutoMapper’? otomatik olarak yap?land?r?r. Entity ve DTO’lar aras?ndaki e?le?tirmeleri tan?mlamak i?in Profile s?n?flar? olu?turulur ve YourProjectNameApplicationModule i?inde yap?land?r?l?r.
MyProjectApplicationAutoMapperProfile.cs (MyProject.Application projesinde):
C#
using AutoMapper;
using MyProject.Books;
using MyProject.Application.Contracts.Books;
namespace MyProject.Application
{
public class MyProjectApplicationAutoMapperProfile : Profile
{
public MyProjectApplicationAutoMapperProfile()
{
/* You can configure your AutoMapper mapping configurations here.
* Alternatively, you can split your mapping configurations
* into multiple profile classes for a better organization. */
CreateMap<Book, BookDto>();
CreateMap<CreateUpdateBookDto, Book>(); // DTO'dan Entity'ye d?n???m
}
}
}
IApplicationService Interface Kullan?m?
IApplicationService aray?z?, bir s?n?f?n bir uygulama servisi oldu?unu belirtir. Bu aray?z? implemente eden s?n?flar, ABP’nin otomatik ba??ml?l?k enjeksiyonu ve Auto API Controller (Bkz. B?l?m 6) ?zellikleri i?in uygundur.
C#
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using MyProject.Application.Contracts.Books;
namespace MyProject.Application.Contracts.Books
{
public interface IBookAppService : IApplicationService
{
Task<BookDto> GetAsync(Guid id);
Task<List<BookDto>> GetListAsync();
Task<BookDto> CreateAsync(CreateUpdateBookDto input);
Task UpdateAsync(Guid id, CreateUpdateBookDto input);
Task DeleteAsync(Guid id);
}
}
Validasyonlar ve ?? Kurallar?n?n Uygulanmas?
Uygulama katman?nda, istemciden gelen verilerin do?ru formatta ve ge?erli oldu?undan emin olmak i?in validasyonlar yap?l?r. Bu validasyonlar genellikle DTO’lar ?zerinde veri a??klamas? (data annotations) nitelikleri kullan?larak veya FluentValidation gibi k?t?phanelerle uygulan?r.
Ayr?ca, baz? i? kurallar? (ancak domain katman?nda olmas? gerekenler de?il) uygulama katman?nda da uygulanabilir. ?rne?in, bir kullan?c?n?n belirli bir i?lemi yapmaya yetkisi olup olmad???n? kontrol etmek.
ABP Features ve ?zellik Kontrol?
ABP Framework, uygulaman?zda Features (?zellikler) ad? verilen bir mekanizma sunar. Bu, belirli i?levlerin veya mod?llerin uygulaman?z?n farkl? s?r?mlerinde veya farkl? kirac?lar i?in etkinle?tirilip devre d??? b?rak?lmas?n? sa?lar. ?rne?in, bir “Premium ?zellik” sadece belirli bir abonelik seviyesine sahip kullan?c?lara sunulabilir.
- ?zellik Tan?mlama:
IFeatureDefinitionContextkullanarak ?zellikler tan?mlan?r (genellikle birModules?n?f?nda). - ?zellik Kullan?m?:
IFeatureCheckerservisi arac?l???yla uygulaman?z?n herhangi bir yerinde (uygulama servisi, UI vb.) bir ?zelli?in etkin olup olmad??? kontrol edilir.
C#
// ?zelli?i tan?mlama (YourProjectNameModule.cs'de)
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpFeaturesConfigurationOptions>(options =>
{
options.AddGroup(
new FeatureGroupDefinition(
"MyFeatures",
"My Features"
).AddFeature(
"MyProject.PremiumFeature",
"false", // Varsay?lan de?er
"This is a premium feature."
)
);
});
}
// Uygulama servisinde ?zelli?i kontrol etme
private readonly IFeatureChecker _featureChecker;
public async Task DoPremiumOperation()
{
if (!await _featureChecker.IsEnabledAsync("MyProject.PremiumFeature"))
{
throw new BusinessException(MyProjectDomainErrorCodes.PremiumFeatureRequired);
}
// Premium i?lem mant???
}
Uygulama katman?, uygulaman?z?n kullan?m senaryolar?n? a??k?a tan?mlayarak ve domain katman?ndan ba??ms?z kalarak, daha temiz ve bak?m? kolay bir kod taban? olu?turman?za yard?mc? olur.