A library of reusable types for implementing Clean Architecture in .NET and ASP.NET Core applications, based heavily on the work of Steve Smith in the following open-source projects:
For the core functionality, only the F23.Kernel library is needed. This library provides types for events, results, query and command handlers, validation, and messaging. For smoother integration with ASP.NET Core, the F23.Kernel.AspNetCore library can be used for easily mapping between core result types and ASP.NET Core IActionResult and model state.
WARNING: This library is currently in a pre-release state, and breaking changes may occur before reaching version 1.0.
What if your day job was contributing to open-source projects and custom AI solutions — and you got paid for it?
We're hiring remote engineers to contribute to cutting-edge AI and custom software projects. 100% remote, 100% real impact. https://www.feature23.com/careers
dotnet add package F23.Kerneldotnet add package F23.Kernel.AspNetCoreclassGetWeatherForecastQueryResult{publicrequiredIReadOnlyList<WeatherForecast>Forecast{get;init;}}classGetWeatherForecastQuery:IQuery<GetWeatherForecastQueryResult>{publicintDaysIntoTheFuture{get;init;}=5;}recordWeatherForecast(DateOnlyDate,intTemperatureC,string?Summary){publicintTemperatureF=>32+(int)(TemperatureC/0.5556);}classGetWeatherForecastQueryHandler(IValidator<GetWeatherForecastQuery>validator,IWeatherForecastRepositoryrepository):IQueryHandler<GetWeatherForecastQuery,GetWeatherForecastQueryResult>{publicasyncTask<Result<GetWeatherForecastQueryResult>>Handle(GetWeatherForecastQueryquery,CancellationTokencancellationToken=default){if(awaitvalidator.Validate(query,cancellationToken)isValidationFailedResultfailed){returnResult<GetWeatherForecastQueryResult>.ValidationFailed(failed.Errors);}varforecast=awaitrepository.GetForecast(query.DaysIntoTheFuture,cancellationToken);varresult=newGetWeatherForecastQueryResult{Forecast=forecast};returnResult<GetWeatherForecastQueryResult>.Success(result);}}builder.Services.RegisterQueryHandler<GetWeatherForecastQuery,GetWeatherForecastQueryResult,GetWeatherForecastQueryHandler>();// Other code omitted for brevityapp.MapGet("/weatherforecast",async(IQueryHandler<GetWeatherForecastQuery,GetWeatherForecastQueryResult>queryHandler)=>{varresult=awaitqueryHandler.Handle(newGetWeatherForecastQuery());returnresult.ToMinimalApiResult();}).WithName("GetWeatherForecast").WithOpenApi();TODO
TODO