private Task HandleEmployeeUpdate(CloudQueueMessage queueMessage, ILogger log) =>
    queueMessage
    .Apply(QueueMessageHandler.FromQueueMessage <EmployeeUpdate>)
    .Apply(message => queryDispatcher.Dispatch(new EmployeeQuery(message.EmployeeId))
           .DoIfNoneOrFail(
               () => log.LogError("Could not find {employeeId}", message.EmployeeId),
               ex => log.LogError(ex, "Could not query for employee {employeeId}", message.EmployeeId)
               )
           .SelectMany(
               employee =>
    {
        var query = new DepartmentEmployeeQuery(employee.Department, employee.Id);

        return(queryDispatcher
               .Dispatch(query)
               .DoIfNoneOrFail(
                   () => log.LogError("Could not find Department Employee for {@query}", query),
                   ex => log.LogError(ex, "Could not query for Department Employee for {@query}", query)));
    },
               (employee, departmentEmployee) => new { employee, departmentEmployee }))
    .Bind(aggregate => commandDispatcher.Dispatch(new DepartmentEmployeeUpdateCommand(aggregate.employee, aggregate.departmentEmployee))
          .DoIfFail(ex => log.LogError(ex, "Could not update Department Employee {departmentEmployeeId} from Employee {employeeId}", aggregate.departmentEmployee.Id, aggregate.employee.Id))
          .Do(de => log.LogInformation("{@departmentEmployee} updated", de))
          .ToTryOption())
    .Bind(departmentEmployee => apiClient.SendNotification(nameof(EmployeeUpdatesQueue), departmentEmployee)
          .DoIfFail(ex => log.LogError(ex, "Could not send API Notification"))
          .Do(_ => log.LogInformation($"API notification sent")))
    .Try();
 private Task HandleEmployeeCreation(CloudQueueMessage queueMessage, ILogger log) =>
 queueMessage
 .Apply(QueueMessageHandler.FromQueueMessage <EmployeeCreation>)
 .Apply(message => queryDispatcher.Dispatch(new EmployeeQuery(message.EmployeeId))
        .DoIfNoneOrFail(
            () => log.LogError("Could not find Employee {employeeId}", message.EmployeeId),
            ex => log.LogError(ex, "Could not query for Employee {employeeId}", message.EmployeeId))
        .Bind(
            employee => commandDispatcher.Dispatch(new DepartmentEmployeeCreateCommand(employee, idGenerator.Generate()))
            .DoIfFail(ex => log.LogError(ex, "Could not create Department Employee for {@employee}", employee))
            .Do(de => log.LogInformation("{@departmentEmployee} created for {employeeId}", de, message.EmployeeId))
            .ToTryOption()
            )
        )
 .Bind(departmentEmployee =>
       apiClient.SendNotification(nameof(EmployeeUpdatesQueue), departmentEmployee)
       .DoIfFail(ex => log.LogError(ex, "Could not send API notification for {@departmentEmployee} creation", departmentEmployee))
       .Do(_ => log.LogInformation($"API notification sent")))
 .Try();
 private Task HandleEmployeePayrollCreation(CloudQueueMessage queueMessage, ILogger log) =>
 queueMessage
 .Apply(QueueMessageHandler.FromQueueMessage <EmployeePayrollCreation>)
 .Apply(message => queryDispatcher.Dispatch(new EmployeeQuery(message.EmployeeId))
        .DoIfNoneOrFail(
            () => log.LogError("Could not find Employee {employeeId}", message.EmployeeId),
            ex => log.LogError(ex, "Could not query for Employee {employeeId}", message.EmployeeId)
            )
        .SelectMany(
            employee => queryDispatcher.Dispatch(new EmployeePayrollQuery(employee.Id, message.EmployeePayrollId))
            .DoIfNoneOrFail(
                () => log.LogError("Could not find Employee Payroll for {employeeId} and {employeePayrollId}", employee.Id, message.EmployeePayrollId),
                ex => log.LogError(ex, "Could not query for Employee Payroll for {employeeId} and {employeePayrollId}", employee.Id, message.EmployeePayrollId)),
            (employee, employeePayroll) => new { employee, employeePayroll })
        )
 .Bind(aggregate => commandDispatcher.Dispatch(new DepartmentPayrollCreateCommand(aggregate.employee, idGenerator.Generate(), aggregate.employeePayroll))
       .DoIfFail(ex => log.LogError(ex, "Could not create Department Payroll for {@employee} and {@payroll}", aggregate.employee, aggregate.employeePayroll))
       .Do(dp => log.LogInformation("{@departmentPayroll} created for {employeeId} {employeePayrollId}", dp, aggregate.employee.Id, aggregate.employeePayroll.Id))
       .ToTryOption())
 .Bind(departmentPayroll => apiClient.SendNotification(nameof(EmployeePayrollUpdatesQueue), departmentPayroll)
       .DoIfFail(ex => log.LogError(ex, "Could not send API notification for {@departmentPayroll} creation", departmentPayroll))
       .Do(_ => log.LogInformation($"API notification sent")))
 .Try();