Mapeg.UseCase.Template 1.1.0

dotnet new install Mapeg.UseCase.Template::1.1.0
                    
This package contains a .NET Template Package you can call from the shell/command line.

Mapeg UseCase Template

MAPEG mikroservislerinde CQRS pattern ile Command ve Query oluşturmak için kullanılan .NET template.

🚀 Ne Yapar?

Bu template tek komutla:

  • Controller oluşturur (sadece --usecaseType all kullanıldığında)
  • Entity oluşturur (Domain layer)
  • DTO oluşturur (Application layer)
  • Commands oluşturur (Create, Update, Delete)
  • Queries oluşturur (Get, GetList, GetPagination)
  • Validators oluşturur (FluentValidation - Command içinde)
  • Filter oluşturur (PaginationFilter için)
  • Configuration oluşturur (Entity Framework konfigürasyonu)
  • Mapping'i otomatik ekler (GeneralMapping.cs'e - post-action ile)

Hızlı Başlangıç

Kurulum

dotnet new install Mapeg.UseCase.Template

Kullanım Örnekleri

ÖNEMLİ: Template'i kullanmadan önce ilgili servisin Application katmanındaki Features klasörüne gitmeniz gerekmektedir.

cd src/Services/[ServisAdı]/[ServisAdı].Application/Features
1. Full CRUD Operations
dotnet new mapeg-usecase --featureName Products --usecaseType all --entityName Product
2. Sadece Command'lar (Create, Update, Delete)
dotnet new mapeg-usecase --featureName Orders --usecaseType command --entityName Order
3. Sadece Query'ler (Get, GetList)
dotnet new mapeg-usecase --featureName Customers --usecaseType query --entityName Customer
4. Entity adı farklı ise
dotnet new mapeg-usecase --featureName UserProfiles --usecaseType all --entityName User
5. Tablo adı belirtmek için
dotnet new mapeg-usecase --featureName Categories --usecaseType all --entityName Category --tableName "CAT_CATEGORY"
6. Return type belirtmek için
dotnet new mapeg-usecase --featureName Reports --usecaseType query --entityName Report --returnType "ReportDetailDto"
7. Servis adı belirtmek için
dotnet new mapeg-usecase --featureName Documents --usecaseType all --entityName Document --serviceName "Belge"

Parametreler

Parametre Kısa Zorunlu Açıklama Örnek
--featureName -fn Feature adı Products, TodoLists
--usecaseType -ut UseCase tipi command, query, all
--entityName Entity adı (varsayılan: featureName) Product, TodoList
--returnType -rt Return tipi (varsayılan: int) ProductDto, List<ProductDto>
--tableName Veritabanı tablo adı IHL_KOMISYON_UYE
--serviceName Servis adı Belge, Ihale

UseCase Tipleri

  • all: Full CRUD operations (Create, Update, Delete, Get, GetList) + Controller
  • command: Sadece command'lar (Create, Update, Delete) - Controller oluşturulmaz
  • query: Sadece query'ler (Get, GetList) - Controller oluşturulmaz

Oluşturulan Dosya Yapısı

Full CRUD (--usecaseType all)

YourService.API/
└── Controllers/
    └── ProductsController.cs            # Full CRUD endpoints

YourService.Application/
├── Dtos/
│   └── ProductsDto.cs                   # DTO class
└── Features/
    └── Products/
        ├── Commands/
        │   ├── CreateProductsCommand.cs # Command + Validator
        │   ├── UpdateProductsCommand.cs # Command + Validator
        │   └── DeleteProductsCommand.cs # Command + Validator
        └── Queries/
            ├── GetProductsQuery.cs           # Single item query
            ├── GetProductsListQuery.cs       # List query
            └── GetProductsPaginationQuery.cs # Pagination query

YourService.Application/
├── Filters/
│   └── ProductsFilter.cs                # Pagination filter

YourService.Domain/
└── Entities/
    └── Product.cs                       # Entity class

YourService.Infrastructure/
└── Configurations/
    └── ProductConfiguration.cs         # EF Core configuration

Sadece Commands (--usecaseType command)

YourService.Application/
├── Dtos/
│   └── OrdersDto.cs                     # DTO class
└── Features/
    └── Orders/
        └── Commands/
            ├── CreateOrdersCommand.cs   # Command + Validator
            ├── UpdateOrdersCommand.cs   # Command + Validator
            └── DeleteOrdersCommand.cs   # Command + Validator

YourService.Domain/
└── Entities/
    └── Order.cs                         # Entity class

Sadece Queries (--usecaseType query)

YourService.Application/
├── Dtos/
│   └── CustomersDto.cs                  # DTO class
└── Features/
    └── Customers/
        └── Queries/
            ├── GetCustomersQuery.cs     # Single item query
            └── GetCustomersListQuery.cs # List query

YourService.Domain/
└── Entities/
    └── Customer.cs                      # Entity class (sadece okuma için)

Dosya İçerikleri

Controller Dosyası Örneği

using MediatR;
using Microsoft.AspNetCore.Mvc;
using ServiceName.Application.Dtos;
using ServiceName.Application.Features.Products.Commands;
using ServiceName.Application.Features.Products.Queries;

namespace ServiceName.API.Controllers;

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private readonly IMediator _mediator;

    public ProductsController(IMediator mediator)
    {
        _mediator = mediator;
    }

    [HttpGet]
    public async Task<ActionResult<List<ProductsDto>>> GetAll()
    {
        var query = new GetProductsListQuery();
        var result = await _mediator.Send(query);
        return Ok(result);
    }

    [HttpGet("{id}")]
    public async Task<ActionResult<ProductsDto>> GetById(int id)
    {
        var query = new GetProductsQuery(id);
        var result = await _mediator.Send(query);
        return Ok(result);
    }

    [HttpPost]
    public async Task<ActionResult<int>> Create([FromBody] ProductsDto dto)
    {
        var command = new CreateProductsCommand(dto);
        var result = await _mediator.Send(command);
        return Ok(result);
    }

    [HttpPut]
    public async Task<ActionResult<int>> Update([FromBody] ProductsDto dto)
    {
        var command = new UpdateProductsCommand(dto);
        var result = await _mediator.Send(command);
        return Ok(result);
    }

    [HttpDelete("{id}")]
    public async Task<ActionResult<int>> Delete(int id)
    {
        var command = new DeleteProductsCommand(id);
        var result = await _mediator.Send(command);
        return Ok(result);
    }
}

Entity Dosyası Örneği

using System.ComponentModel.DataAnnotations.Schema;
using BuildingBlocks.Interfaces;

namespace ServiceName.Domain.Entities;

[Table(name: "PRD_PRODUCTS")]
public class Product : HasFullCrudInfo, IEntityBase, IIdentifier<int>
{
    [Column(name: "ID")]
    public int Id { get; set; }
    
    [Column(name: "NAME")]
    public string? Name { get; set; }
    
    [Column(name: "PRICE")]
    public decimal Price { get; set; }
    
    [Column(name: "STOCK_QUANTITY")]
    public int StockQuantity { get; set; }
}

DTO Dosyası Örneği

namespace ServiceName.Application.Dtos;

public class ProductsDto
{
    public int Id { get; set; }
    public string? Name { get; set; }
    public decimal Price { get; set; }
    public int StockQuantity { get; set; }
}

Command Dosyası Örneği

using BuildingBlocks.CQRS.GenericExtensions.Commands;
using FluentValidation;
using ServiceName.Application.Dtos;

namespace ServiceName.Application.Features.Products.Commands;

public class CreateProductsCommand(ProductsDto dto) 
    : CreateGenericCommand<ProductsDto, Product>(dto);

public class CreateProductsCommandValidator : AbstractValidator<CreateProductsCommand>
{
    public CreateProductsCommandValidator()
    {
        // Validation rules
    }
}

Query Dosyası Örneği

using BuildingBlocks.CQRS.GenericExtensions.Queries;
using ServiceName.Application.Dtos;

namespace ServiceName.Application.Features.Products.Queries;

public record GetProductsQuery : GetGenericQuery<Product, ProductsDto>
{
    private readonly int _id;
    
    public GetProductsQuery(int id) : base(x => x.Id == id)
    {
        _id = id;
    }
}

Özellikler

  • Controller oluşturma: API endpoint'leri otomatik oluşturulur (sadece all tipinde)
  • Entity oluşturma: Domain katmanında entity sınıfı oluşturulur
  • DTO oluşturma: Application katmanında DTO sınıfı oluşturulur
  • Command/Query oluşturma: CQRS pattern'e uygun sınıflar
  • Validator entegrasyonu: FluentValidation ile command dosyalarının içinde
  • Generic handler kullanımı: Ayrı handler yazılması gerekmez
  • BuildingBlocks.CQRS.GenericExtensions otomatik kullanımı
  • Namespace'ler proje yapısına göre otomatik ayarlanır
  • Tablo adı desteği: Entity'de Table attribute ile özelleştirilebilir
  • Column mapping: Entity property'leri için Column attribute desteği

Detaylı Örnekler

Örnek 1: E-Ticaret Ürün Yönetimi

# Ürünler için full CRUD
dotnet new mapeg-usecase --featureName Products --usecaseType all --entityName Product

# Kategoriler için sadece query
dotnet new mapeg-usecase --featureName Categories --usecaseType query --entityName Category

# Siparişler için özel tablo adı ile
dotnet new mapeg-usecase --featureName Orders --usecaseType all --entityName Order --tableName "ORD_ORDERS"

Örnek 2: Kullanıcı Yönetimi

# Kullanıcı profilleri
dotnet new mapeg-usecase --featureName UserProfiles --usecaseType all --entityName User --returnType "UserProfileDto"

# Roller için sadece query
dotnet new mapeg-usecase --featureName Roles --usecaseType query --entityName Role

Örnek 3: Belge Yönetimi (MAPEG Projesi)

# Belge servisi için
cd src/Services/Belge/Belge.Application/Features

# Belgeler için full CRUD
dotnet new mapeg-usecase --featureName Belgeler --usecaseType all --entityName Belge --serviceName "Belge"

# Belge tipleri için
dotnet new mapeg-usecase --featureName BelgeTipleri --usecaseType query --entityName BelgeTip --tableName "BLG_BELGE_TIP"

Validation Örnekleri

Template otomatik olarak validator sınıfları oluşturur. Bunları projenize göre özelleştirmeniz gerekir:

Create Command Validator

public class CreateProductsCommandValidator : AbstractValidator<CreateProductsCommand>
{
    public CreateProductsCommandValidator()
    {
        RuleFor(x => x.Dto.Name)
            .NotEmpty().WithMessage("Ürün adı zorunludur")
            .MaximumLength(100).WithMessage("Ürün adı 100 karakterden uzun olamaz");
            
        RuleFor(x => x.Dto.Price)
            .GreaterThan(0).WithMessage("Fiyat 0'dan büyük olmalıdır");
    }
}

Update Command Validator

public class UpdateProductsCommandValidator : AbstractValidator<UpdateProductsCommand>
{
    public UpdateProductsCommandValidator()
    {
        RuleFor(x => x.Dto.Id)
            .GreaterThan(0).WithMessage("Id 0'dan büyük olmalıdır");
            
        RuleFor(x => x.Dto.Name)
            .NotEmpty().WithMessage("Ürün adı zorunludur");
    }
}

🔄 Birden Fazla UseCase Ekleme

Aynı serviste birden fazla UseCase eklediğinizde --force parametresini kullanmanız gerekebilir:

# İlk UseCase
dotnet new mapeg-usecase --featureName Products --usecaseType all --entityName Product

# İkinci ve sonraki UseCase'ler
dotnet new mapeg-usecase --featureName Orders --usecaseType command --entityName Order --force

Neden --force gerekli? .template klasöründeki mapping scriptleri her UseCase için güncellendiğinden, ikinci kullanımda üzerine yazma onayı gerekir.

Post-Action: Otomatik Mapping Ekleme

Template kullanıldığında, GeneralMapping.cs dosyasına mapping'i otomatik eklemek için bir post-action çalışır:

  1. Otomatik Ekleme: Template oluşturulduktan sonra bash .template/add-mapping.sh scripti çalışır
  2. Script Özellikleri:
    • GeneralMapping.cs dosyasını otomatik bulur
    • Mapping zaten varsa tekrar eklemez
    • TODO comment'inden sonra veya constructor'ın sonuna ekler
  3. Manuel Ekleme: Script çalışmazsa şu satırı GeneralMapping.cs'e ekleyin:
    CreateMap<EntityName, FeatureNameDto>().ReverseMap();
    

Notlar

  • Çoklu katman desteği: Template Application ve Domain katmanlarında dosyalar oluşturur, API katmanına Controller sadece all tipinde eklenir
  • Controller sadece all tipinde: command ve query tiplerinde Controller oluşturulmaz, manuel eklemeniz gerekir
  • Entity ve DTO şablonları: Temel yapı oluşturulur, property'leri sizin eklemeniz gerekir
  • Validator sınıfları: Command dosyalarıyla aynı dosyada oluşturulur (ayrı dosya değil)
  • Generic handler kullanımı: BuildingBlocks.CQRS.GenericExtensions sayesinde ayrı handler yazılmaz
  • Namespace otomasyonu: Template bulunduğu projenin namespace'ini otomatik algılar
  • Tablo adı özelleştirme: --tableName parametresi ile veritabanı tablo adı belirtilebilir
  • Query'ler için validator yoktur: Genelde gerekli değildir, ihtiyaç olursa manuel eklenebilir

Gereksinimler

  • .NET 9.0 veya üzeri
  • BuildingBlocks.CQRS paketi
  • BuildingBlocks.Repository paketi
  • FluentValidation paketi

Template Çıktısı Örneği

Aşağıdaki komutu çalıştırdığınızda:

dotnet new mapeg-usecase --featureName Products --usecaseType all --entityName Product --tableName "PRD_PRODUCTS"

Şu dosyalar oluşturulur:

✅ Created: API/Controllers/ProductsController.cs
✅ Created: Application/Dtos/ProductsDto.cs
✅ Created: Application/Features/Products/Commands/CreateProductsCommand.cs
✅ Created: Application/Features/Products/Commands/UpdateProductsCommand.cs
✅ Created: Application/Features/Products/Commands/DeleteProductsCommand.cs
✅ Created: Application/Features/Products/Queries/GetProductsQuery.cs
✅ Created: Application/Features/Products/Queries/GetProductsListQuery.cs
✅ Created: Domain/Entities/Product.cs

Total: 8 files created

📞 Destek

MAPEG Development Team

yazilim@mapeg.gov.tr

Sorun Giderme

Template bulunamıyor hatası

# Template'i yeniden yükleyin
dotnet new uninstall Mapeg.UseCase
dotnet new install /path/to/templates/Mapeg.UseCase

Namespace hataları

Template otomatik olarak bulunduğu klasördeki namespace'i kullanır. ServiceName.Application yerine gerçek proje namespace'i gelecektir.

Validation çalışmıyor

FluentValidation'ın DI container'a eklendiğinden emin olun:

services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
  • net9.0

    • No dependencies.

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
1.1.0 93 8/15/2025
1.0.1 112 8/15/2025
1.0.0 107 8/15/2025