Choose your hero
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"));
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.