Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adopt Context Receivers #71

Open
idugalic opened this issue Feb 19, 2022 · 0 comments
Open

Adopt Context Receivers #71

idugalic opened this issue Feb 19, 2022 · 0 comments

Comments

@idugalic
Copy link
Member

Context receivers enable context-dependent declarations in Kotlin.

It enables composing contexts without using inheritance, which can simplify the application layer of the systems / orchestrate the logic's execution.

It will eliminate the need of application interfaces, for example interface EventSourcingAggregate<C, S, E> : IDecider<C, S, E>, EventRepository<C, E> or interface StateStoredAggregate<C, S, E> : IDecider<C, S, E>, StateRepository<C, S>

/**
 * Event-sourced algorithm
 * Computes new Events based on the previous Events and the Command.
 */
context (Decider<C, S, E>, C)
private fun <C, S, E> Flow<E>.computeNewEvents(): Flow<E> = flow {
    val currentState = fold(initialState) { s, e -> evolve(s, e) }
    val resultingEvents = decide(this@C, currentState)
    emitAll(resultingEvents)
}

/**
 * State-stored algorithm
 * Computes new State based on the previous State and the Command.
 */
context (Decider<C, S, E>, C)
private suspend fun <C, S, E> S?.computeNewState(): S {
    val currentState = this ?: initialState
    val events = decide(this@C, currentState)
    return events.fold(currentState) { s, e -> evolve(s, e) }
}

/**
 * Publish command - Event-sourced decider
 */
context (Decider<C, S, E>, EventRepository<C, E>)
fun <C, S, E> C.publish(): Flow<E> = fetchEvents().computeNewEvents().save()

/**
 * Publish command - State-stored decider
 */
context (Decider<C, S, E>, StateRepository<C, S>)
suspend fun <C, S, E> C.publish(): S = fetchState().computeNewState().save()

https://gist.github.com/idugalic/232bc21490f4a8976bc31e0acf548831

A plan is to alternatively implement context-dependent declarations by keeping current interfaces as a valid option: EventSourcingAggregate, StateStoredAggregate, ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant