public static async Task <IServiceResponse <IEnumerable <T2> > > BindManyAsync <T, T2>( this IServiceResponse <IEnumerable <T> > serviceResponse, Func <T, Task <IServiceResponse <T2> > > bindFunc) { if (serviceResponse.IsLeft) { return(serviceResponse.CreateGenericErrorResponse <IEnumerable <T>, IEnumerable <T2> >(serviceResponse.GetLeft())); } var result = new List <T2>(); foreach (var element in serviceResponse.GetRight()) { var elementResponse = await bindFunc(element); if (elementResponse.IsLeft) { return(serviceResponse.CreateGenericErrorResponse <IEnumerable <T>, IEnumerable <T2> >(elementResponse.GetLeft())); } result.Add(elementResponse.GetRight()); } return(serviceResponse.CreateGenericDataResponse(result)); }
/// <summary> /// Invokes the specified action if <paramref name="serviceResponse"/>.IsRight. /// Returns the current <see cref="IServiceResponse{T}" /> instance. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="serviceResponse">The service response.</param> /// <param name="action">The action to invoke.</param> /// <returns>The current <see cref="IServiceResponse{T}" /> instance.</returns> public static IServiceResponse <T> Let <T>(this IServiceResponse <T> serviceResponse, Action <T> action) { if (serviceResponse.IsRight) { action.Invoke(serviceResponse.GetRight()); } return(serviceResponse); }
/// <summary> /// If <paramref name="serviceResponse"/>.IsLeft, returns a new <see cref="IServiceResponse{T2}" /> instance with the current /// <paramref name="serviceResponse"/>.Error. Otherwise, it binds the <paramref name="serviceResponse"/>.Data into the specified /// <paramref name="bindingFunction" />. /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="T2">The type of the next <see cref="IServiceResponse{T2}" /> to return.</typeparam> /// <param name="serviceResponse">The service response.</param> /// <param name="bindingFunction">The binding function.</param> /// <returns>Instance of <see cref="IServiceResponse{T2}" />.</returns> public static IServiceResponse <T2> Bind <T, T2>(this IServiceResponse <T> serviceResponse, Func <T, IServiceResponse <T2> > bindingFunction) { if (serviceResponse.IsLeft) { return(serviceResponse.CreateGenericErrorResponse <T, T2>(serviceResponse.GetLeft())); } return(bindingFunction.Invoke(serviceResponse.GetRight())); }
/// <summary> /// Returns the value of <typeparamref name="T"/> if there is no error. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="serviceResponse">The service response.</param> /// <returns><typeparamref name="T"/>.</returns> /// <exception cref="System.InvalidOperationException">Cannot return right of either when left (errors) exist.</exception> public static T FromRight <T>(this IServiceResponse <T> serviceResponse) { if (!serviceResponse.IsRight) { throw new InvalidOperationException("Cannot return right of either when is left."); } return(serviceResponse.GetRight()); }
/// <summary> /// If <paramref name="serviceResponse"/>.IsLeft, returns a new <see cref="IServiceResponse{T2}" /> instance with the current /// <paramref name="serviceResponse"/>.Error. Otherwise, it binds the <paramref name="serviceResponse"/>.Data into /// the specified <paramref name="mappingFunction" />. /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="T2">The type of the next <see cref="IServiceResponse{T2}" /> to return.</typeparam> /// <param name="serviceResponse">The service response.</param> /// <param name="mappingFunction">The mapping function.</param> /// <returns>Instance of <see cref="IServiceResponse{T2}" />.</returns> public static IServiceResponse <T2> Fmap <T, T2>(this IServiceResponse <T> serviceResponse, Func <T, T2> mappingFunction) { if (serviceResponse.IsLeft) { return(serviceResponse.CreateGenericErrorResponse <T, T2>(serviceResponse.GetLeft())); } T2 result = mappingFunction.Invoke(serviceResponse.GetRight()); return(serviceResponse.CreateGenericDataResponse(result)); }
/// <summary> /// If <seealso cref="IServiceResponse{T}.IsLeft" />, returns a new <see cref="IServiceResponse{T2}" /> instance with the current /// <seealso cref="IServiceResponse{T}.Error" />. Else, binds the <seealso cref="IServiceResponse{T}.Data" /> into the /// specified <paramref name="bindFunc" />. /// </summary> /// <typeparam name="T">The type of the current <see cref="IServiceResponse{T}"/>.</typeparam> /// <typeparam name="T2">The type of the next <see cref="IServiceResponse{T2}" /> to return.</typeparam> /// <param name="serviceResponse">The service response.</param> /// <param name="bindFunc">The binding function.</param> /// <returns>Instance of <see cref="IServiceResponse{T2}" />.</returns> public static Task <IServiceResponse <T2> > BindAsync <T, T2>( this IServiceResponse <T> serviceResponse, Func <T, Task <IServiceResponse <T2> > > bindFunc) { if (serviceResponse.IsLeft) { return(Task.FromResult(serviceResponse.CreateGenericErrorResponse <T, T2>(serviceResponse.GetLeft()))); } return(bindFunc(serviceResponse.GetRight())); }
/// <summary> /// Invokes the specified action if <paramref name="serviceResponse"/>.<see cref="IServiceResponse{T}.IsRight" />. /// Returns the current <paramref name="serviceResponse"/> instance. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="serviceResponse">The service response.</param> /// <param name="letAction">The let function.</param> /// <returns>Returns the current <paramref name="serviceResponse"/> instance unless /// <paramref name="letAction"/> returns a faulted task. <see cref="Task.IsFaulted"/></returns> public static Task <IServiceResponse <T> > LetAsync <T>( this IServiceResponse <T> serviceResponse, Action <T> letAction) { if (serviceResponse.IsLeft) { return(Task.FromResult(serviceResponse)); } // TODO: (DG) This can yield unexpected results of the action is an asyncVoid and throws an exception! letAction(serviceResponse.GetRight()); return(Task.FromResult(serviceResponse)); }
/// <summary> /// Raises the specified event if <paramref name="onRightOnly" /> is false or the <paramref name="serviceResponse" />.IsRight. /// Event handlers may be executed in parallel. All handlers are run even if one throws an exception. /// If an exception is thrown, this method returns a new <see cref="ServiceResponse{T}" /> with an error representing the thrown exceptions. /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="TEvent">The type of the T event.</typeparam> /// <param name="serviceResponse">The service response.</param> /// <param name="eventManager">The event manager.</param> /// <param name="eventFactory">The function to create the event.</param> /// <param name="onRightOnly">Determines whether to raise the event in the case the serviceResponse is left.</param> /// <returns>Task<IServiceResponse<T>>.</returns> public static Task <IServiceResponse <T> > RaiseAsync <T, TEvent>( this IServiceResponse <T> serviceResponse, IManageEvents eventManager, Func <T, TEvent> eventFactory, Boolean onRightOnly = true) { if (onRightOnly && serviceResponse.IsLeft) { return(Task.FromResult(serviceResponse)); } var eventParam = serviceResponse.IsRight ? serviceResponse.GetRight() : default(T); return(eventManager.Raise(eventFactory(eventParam)) .ContinueWith(task => task.IsFaulted ? new ErrorResponse <T>(task.Exception.ToError()) : serviceResponse, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default)); }
/// <summary> /// Invokes the specified action if <see cref="IServiceResponse{T}.IsRight" />. /// Returns the current <paramref name="serviceResponse"/> instance unless <paramref name="letFunc"/> /// returns a faulted task. <see cref="Task.IsFaulted"/> /// </summary> /// <typeparam name="T"></typeparam> /// <param name="serviceResponse">The service response.</param> /// <param name="letFunc">The let function.</param> /// <returns>Returns the current <paramref name="serviceResponse"/> instance unless /// <paramref name="letFunc"/> returns a faulted task. <see cref="Task.IsFaulted"/></returns> public static Task <IServiceResponse <T> > LetAsync <T>( this IServiceResponse <T> serviceResponse, Func <T, Task> letFunc) { if (serviceResponse.IsLeft) { return(Task.FromResult(serviceResponse.CreateGenericErrorResponse(serviceResponse.GetLeft()))); } return(letFunc(serviceResponse.GetRight()) .ContinueWith(task => { if (task.IsFaulted) { return new ErrorResponse <T>(task.Exception.ToError()); } return serviceResponse; }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default)); }