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));
        }
Exemple #2
0
        /// <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);
        }
Exemple #3
0
        /// <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()));
        }
Exemple #4
0
        /// <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());
        }
Exemple #5
0
        /// <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));
        }
Exemple #8
0
        /// <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&lt;IServiceResponse&lt;T&gt;&gt;.</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));
        }