Write elegant and testeable solutions on C# using a Monadic Framework.

Choose your hero

From Notation

  await 
    // Try to create an order
    from maybeOrder in
        from order in _orderRepository.GetByIdAsync(orderId)
        select OrderBehavior.TryCheckout(order)

    // Update database
    from result in maybeOrder.AwaitSideEffect(_orderRepository.UpdateAsync)

    // Return results
    select result.Match(Ok, InternalServerError("Error"));

Fluent Notation

  return await 
      // Try to create an order
      _orderRepository.GetByIdAsync(orderId)    
      .Select(order => OrderBehavior.TryCheckout(order))

      // Update database
      .SelectMany(m => m.AwaitSideEffect(_orderRepository.UpdateAsync))
      
      // Return results
      .Select(m => m.Match(Ok, InternalServerError("Error")));

Inject Behaviors not Dependencies

With a monadic architecture your applications are going to have a pure business logic that allows you to write easy tests and do not depend of any other layer. Also, your side effects are going to be centralized.

Instead of injecting the dependencies in all your project, you just have to inject the behavior with the monads giving live the pure business logic interacting with the exterior world.