如何使用扩展语言函子来处理存储库API中的错误?

时间:2019-02-22 11:40:39

标签: c# functional-programming either

我正在使用language-ext库,该库包含C#(及其较小的sibling csharp-monad)的功能模式,我想应用某些模式来处理ASP.NET Core中的错误。应用。

在我的应用程序中,我通常具有以下几层:

  • ASP.NET操作(REST API表面)层
  • 域服务层
  • 持久层/存储库
  • 数据库层

简化代码示例:

[Route("api/v1/[controller]")]
public class FlightsController : Controller
{
    private readonly IFlightService _flightService;
    private readonly IDistanceCalculator _distanceCalculator;

    // [...]

    public FlightsController(IFlightService flightService, IDistanceCalculator distanceCalculator)
    {
        _flightService = flightService;
        _distanceCalculator = distanceCalculator;
    }

    [HttpGet]
    public IActionResult Get()
    {
        var result = _flightService.GetFlights();

        switch (result)
        {
            case Success<List<FlightDTO>> success:
                var flights = new List<FlightInformations>();
                success.Value.ForEach(x => flights.Add(new FlightInformations(x)));
                return Ok(flights);
            case Failure<List<FlightDTO>> failure:
                return StatusCode((int) HttpStatusCode.InternalServerError, failure.Errors);
            default:
                return StatusCode((int) HttpStatusCode.InternalServerError, "Unexpected error");
        }
    }
}

public class FlightService : IFlightService
{
    private readonly IFlightRepository _flightRepository;

    public FlightService(IFlightRepository flightRepository)
    {
        _flightRepository = flightRepository;
    }

    // [...]

    public Result<List<FlightDTO>> GetFlights()
    {
        var res = _flightRepository.SelectFlights();
        switch (res)
        {
            case Success<List<Flight>> success:
                var flights = new List<FlightDTO>();
                success.Value.ForEach(x => flights.Add(new FlightDTO(x)));
                return Result<List<FlightDTO>>.Ok(flights);
            case Failure<List<Flight>> failure:
                return Result<List<FlightDTO>>.Fail(failure.Errors);
            default:
                return Result<List<FlightDTO>>.Fail(new List<string>() {"An error occured"});
        }
    }
}

public class FlightRepository : IFlightRepository
{
    private readonly FlightManagerDbContext _context;

    public FlightRepository(FlightManagerDbContext context)
    {
        _context = context;
    }

    // [...]

    public Result<List<Flight>> SelectFlights()
    {
        try
        {
            return Result<List<Flight>>.Ok(_context.Flight.Any()
                ? _context.Flight.ToList()
                : new List<Flight>());
        }
        catch (Exception e)
        {
            return Result<List<Flight>>.Fail(new List<string>() {$"An error occured,{e.Message}"});
        }
    }
}

我想避免直接使用try / catch而改用二者之一,我该如何实现?

1 个答案:

答案 0 :(得分:1)

该项目利用language-ext为ASP.NET Core提供了一些错误处理支持:https://github.com/NickDarvey/LanguageExt.AspNetCore

这个问题有点太宽泛,无法涉及更具体的内容。