Метод рефакторинга, возвращающий значение из асинхронной задачи> к EitherAsync - PullRequest
0 голосов
/ 05 декабря 2018

Я создаю прототип language-ext и стиль функционального кода для библиотеки веб-сервера, которую можно использовать в моих проектах.Мне действительно нравится связывание async шагов с использованием синтаксиса запроса LINQ, но теперь я столкнулся с такой проблемой компилятора: language-ext Задача Either с несколькими предложениями from .

Для реализации предложенного решенияв этой ссылке мне нужно было бы провести рефакторинг этого метода:

private static async Task<Either<RouteError, object>> DispatchRequest<T>(
    IRequestDispatcher requestDispatcher,
    T request)
    where T : class, IRequest
{
    var result = await requestDispatcher.Send(request);
    return result.Match<Either<RouteError, object>>(
        Some: x => x,
        None: () => new NotFoundError(),
        Fail: ex => new InternalServerError(ex));
}

, где requestDispatcher - это реализация:

public interface IRequestDispatcher
{
    Task<OptionalResult<object>> Send<T>(T request) where T : IRequest;
}

Вместо этого мне нужен метод с этой сигнатурой, чтобыего легче использовать в выражениях LINQ:

private static EitherAsync<RouteError, object> DispatchRequest<T>(
    IRequestDispatcher requestDispatcher,
    T request)
    where T : class, IRequest
{ 
  // What should the implementation look like? 
} 

Я не могу понять, как создать метод, чтобы я мог await и затем возвращать влево или вправо на основе результата.Все, что я пробовал до сих пор, также выглядит безобразно по сравнению с красивой и чистой исходной реализацией с возвращаемым значением Task.

1 Ответ

0 голосов
/ 07 декабря 2018

Похоже, Send возвращает TryOption?Если это так, то вы можете сделать это:

private static EitherAsync<RouteError, object> DispatchRequest<T>(
    IRequestDispatcher requestDispatcher, T request)
    where T : class, IRequest =>
        Send(request)
            .ToAsync();
            .Match(Some: Right<RouteError, object>,
                   None: () => Left<RouteError, object>(new NotFoundError()),
                   Fail: ex => Left<RouteError, object>(new InternalServerError(ex)))
            .ToAsync();

Что преобразует TryOption в TryOptionAsync, вызывая ToAsync на Task<TryOption<object>>, а затем сопоставляет на этом TryOptionAsyncвернуть Task<Either<RouteError, object>>, а затем, наконец, вызвать ToAsync(), чтобы преобразовать Task в EitherAsync.

...