CleanCodeJN.GenericApis
1.0.0
See the version list below for details.
dotnet add package CleanCodeJN.GenericApis --version 1.0.0
NuGet\Install-Package CleanCodeJN.GenericApis -Version 1.0.0
<PackageReference Include="CleanCodeJN.GenericApis" Version="1.0.0" />
<PackageVersion Include="CleanCodeJN.GenericApis" Version="1.0.0" />
<PackageReference Include="CleanCodeJN.GenericApis" />
paket add CleanCodeJN.GenericApis --version 1.0.0
#r "nuget: CleanCodeJN.GenericApis, 1.0.0"
#:package CleanCodeJN.GenericApis@1.0.0
#addin nuget:?package=CleanCodeJN.GenericApis&version=1.0.0
#tool nuget:?package=CleanCodeJN.GenericApis&version=1.0.0
Generic Web Apis
CRUD support for (Minimal) WebAPIs with the power of Mediator pattern, Automapper, DataRepositories and Entity Framework
This CleanCodeJN package uses build-in Command-Abstraction to use basic CRUD operations with the ability to customize complex business logic by the power of the the Integration/Operation Segregation Principle.
Features
- CRUD APIs build in seconds
- Uses Mediator to abstract build-in and custom complex business logic
- Uses DataRepositories to abstract Entity Framework from business logic
- Enforces IOSP (Integration/Operation Segregation Principle) for commands
- Easy to mock and test
- On latest .NET 8.0
How to use
- Use CleanCodeJN Generic Repositories
- Add RegisterRepositoriesCommandsWithAutomapper<IDataContext>() to your Program.cs
- Add app.RegisterApis() to your Program.cs
- Start writing Apis by implementing IApi
- Extend standard CRUD operations by specific Where() and Include() clauses
- Use IOSP for complex business logic
Step by step explanation
Add RegisterRepositoriesCommandsWithAutomapper<IDataContext>() to your Program.cs:
builder.Services.RegisterRepositoriesCommandsWithAutomapper<MyDbContext>(cfg =>
{
cfg.CreateMap<Customer, CustomerPutDto>().ReverseMap();
cfg.CreateMap<Customer, CustomerPostDto>().ReverseMap();
cfg.CreateMap<Customer, CustomerGetDto>().ReverseMap();
});
Add app.RegisterApis() to your Program.cs:
app.RegisterApis();
Start writing Apis by implementing IApi:
public class CustomersV1Api : IApi
{
public List<string> Tags => ["Customers V1"];
public string Route => $"api/v1/customers";
public List<Func<WebApplication, RouteHandlerBuilder>> HttpMethods =>
[
app => app.MapGet<Customer, CustomerGetDto>(Route, Tags),
app => app.MapGetById<Customer, CustomerGetDto>(Route, Tags),
app => app.MapPut<Customer, CustomerPutDto, CustomerGetDto>(Route, Tags),
app => app.MapPost<Customer, CustomerPostDto, CustomerGetDto>(Route, Tags),
// Or use a custom Command
app => app.MapDeleteRequest(Route, Tags, async (int id, [FromServices] ApiBase api) =>
await api.Handle<Customer, CustomerGetDto>(new DeleteRequest<Customer> { Id = id }))
];
}
Extend standard CRUD operations by specific Where() and Include() clauses
public class CustomersV1Api : IApi
{
public List<string> Tags => ["Customers V1"];
public string Route => $"api/v1/customers";
public List<Func<WebApplication, RouteHandlerBuilder>> HttpMethods =>
[
app => app.MapGet<Customer, CustomerGetDto>(Route, Tags, where: x => x.Name.StartsWith("a")),
];
}
Use IOSP for complex business logic
Derive from BaseIntegrationCommand:
public class YourIntegrationCommand(ICommandExecutionContext executionContext)
: BaseIntegrationCommand(executionContext), IRequestHandler<YourIntegrationRequest, BaseResponse>
Write Extensions on ICommandExecutionContext with Built in Requests or with your own:
public static ICommandExecutionContext CustomerGetByIdRequest(
this ICommandExecutionContext executionContext, int customerId)
=> executionContext.WithRequest(
() => new GetByIdRequest<Customer>
{
Id = customerId,
Includes = [x => x.Invoices, x => x.OtherDependentTable],
},
CommandConstants.CustomerGetById);
See the how clean your code will look like at the end
public class YourIntegrationCommand(ICommandExecutionContext executionContext)
: BaseIntegrationCommand(executionContext), IRequestHandler<YourIntegrationRequest, BaseResponse>
{
public async Task<BaseResponse> Handle(YourIntegrationRequest request, CancellationToken cancellationToken) =>
await ExecutionContext
.CandidateGetByIdRequest(request.Dto.CandidateId)
.CustomerGetByIdRequest(request.Dto.CustomerIds)
.GetOtherStuffRequest(request.Dto.XYZType)
.PostSomethingRequest(request.Dto)
.SendMailRequest()
.Execute(cancellationToken);
}
Sample Code
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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. |
-
net8.0
- AutoMapper (>= 13.0.1)
- CleanCodeJN.Repository.EntityFramework (>= 1.1.1)
- MediatR (>= 12.2.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on CleanCodeJN.GenericApis:
| Package | Downloads |
|---|---|
|
CleanCodeJN.GenericApis.ServiceBusConsumer
This CleanCodeJN package for Service Bus simplifies the development of asynchronous microservices by providing a framework that leverages the power of MediatR and IOSP to consume service bus events from topics and execute commands to process these events. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 5.0.0 | 282 | 11/12/2025 |
| 4.2.10 | 146 | 10/24/2025 |
| 4.2.9 | 182 | 10/22/2025 |
| 4.2.8 | 168 | 10/21/2025 |
| 4.2.7 | 168 | 10/20/2025 |
| 4.2.6 | 168 | 10/20/2025 |
| 4.2.5 | 140 | 10/18/2025 |
| 4.2.4 | 132 | 10/17/2025 |
| 4.2.3 | 113 | 10/17/2025 |
| 4.2.2 | 125 | 10/17/2025 |
| 4.2.1 | 133 | 10/17/2025 |
| 4.2.0 | 134 | 10/17/2025 |
| 4.1.10 | 334 | 9/18/2025 |
| 4.1.9 | 230 | 5/28/2025 |
| 4.1.8 | 226 | 5/21/2025 |
| 4.1.7 | 187 | 5/20/2025 |
| 4.1.6 | 225 | 5/19/2025 |
| 4.1.5 | 206 | 5/19/2025 |
| 4.1.4 | 233 | 4/3/2025 |
| 4.1.3 | 238 | 4/2/2025 |
| 4.1.2 | 218 | 4/2/2025 |
| 4.1.1 | 178 | 3/28/2025 |
| 4.1.0 | 190 | 3/28/2025 |
| 4.0.3 | 196 | 3/27/2025 |
| 4.0.2 | 189 | 3/27/2025 |
| 4.0.1 | 557 | 3/25/2025 |
| 4.0.0 | 150 | 2/28/2025 |
| 3.6.1 | 162 | 2/7/2025 |
| 3.6.0 | 245 | 12/12/2024 |
| 3.5.1 | 172 | 12/7/2024 |
| 3.5.0 | 163 | 11/19/2024 |
| 3.4.1 | 206 | 11/10/2024 |
| 3.4.0 | 199 | 11/10/2024 |
| 3.3.0 | 186 | 10/21/2024 |
| 3.2.2 | 226 | 10/20/2024 |
| 3.2.1 | 213 | 10/20/2024 |
| 3.2.0 | 185 | 10/20/2024 |
| 3.1.9 | 208 | 10/18/2024 |
| 3.1.8 | 178 | 10/9/2024 |
| 3.1.7 | 155 | 10/8/2024 |
| 3.1.6 | 180 | 10/8/2024 |
| 3.1.5 | 206 | 9/25/2024 |
| 3.1.4 | 201 | 9/12/2024 |
| 3.1.3 | 184 | 9/12/2024 |
| 3.1.2 | 179 | 9/12/2024 |
| 3.1.1 | 199 | 9/11/2024 |
| 3.1.0 | 148 | 9/9/2024 |
| 3.0.4 | 175 | 9/6/2024 |
| 3.0.3 | 160 | 9/6/2024 |
| 3.0.2 | 199 | 9/3/2024 |
| 3.0.1 | 142 | 7/30/2024 |
| 3.0.0 | 219 | 5/24/2024 |
| 2.2.0 | 167 | 5/23/2024 |
| 2.1.1 | 192 | 5/22/2024 |
| 2.1.0 | 201 | 5/15/2024 |
| 2.0.8 | 164 | 5/14/2024 |
| 2.0.7 | 181 | 5/14/2024 |
| 2.0.6 | 173 | 5/14/2024 |
| 2.0.5 | 182 | 5/13/2024 |
| 2.0.4 | 146 | 5/13/2024 |
| 2.0.3 | 150 | 5/12/2024 |
| 2.0.2 | 185 | 5/11/2024 |
| 2.0.1 | 160 | 5/8/2024 |
| 2.0.0 | 177 | 5/7/2024 |
| 1.1.1 | 180 | 5/7/2024 |
| 1.1.0 | 196 | 5/7/2024 |
| 1.0.6 | 188 | 5/7/2024 |
| 1.0.5 | 190 | 5/7/2024 |
| 1.0.4 | 191 | 5/7/2024 |
| 1.0.3 | 191 | 5/7/2024 |
| 1.0.2 | 206 | 5/6/2024 |
| 1.0.1 | 189 | 5/6/2024 |
| 1.0.0 | 175 | 5/6/2024 |
First Version.