-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathPostgresUnitOfWork.cs
More file actions
51 lines (41 loc) · 3.33 KB
/
Copy pathPostgresUnitOfWork.cs
File metadata and controls
51 lines (41 loc) · 3.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
namespace CoreEx.Database.Postgres;
/// <summary>
/// Provides the transactional <see cref="IUnitOfWork"/> implementation for <see cref="PostgresDatabase"/> including support for a <see href="https://microservices.io/patterns/data/transactional-outbox.html">transactional outbox</see>.
/// </summary>
/// <param name="database">The <see cref="PostgresDatabase"/>.</param>
/// <param name="outbox">The optional <see cref="IEventPublisher"/>.</param>
/// <param name="invoker">The optional <see cref="PostgresUnitOfWorkInvoker"/> used to orchestrate the <see cref="IUnitOfWork"/> functionality.</param>
public sealed class PostgresUnitOfWork(PostgresDatabase database, IEventPublisher? outbox = null, PostgresUnitOfWorkInvoker? invoker = null) : IDatabaseUnitOfWork
{
/// <inheritdoc/>
IDatabase IDatabaseUnitOfWork.Database => Database;
/// <summary>
/// Gets the underlying <see cref="PostgresDatabase"/>.
/// </summary>
public PostgresDatabase Database { get; } = database.ThrowIfNull();
/// <summary>
/// Gets the optional <see cref="IEventPublisher"/> to be used as a <see href="https://microservices.io/patterns/data/transactional-outbox.html">transactional outbox</see>.
/// </summary>
/// <remarks>Where provided, the <see cref="IEventPublisher.PublishAsync(CancellationToken)"/> is invoked as part of the underlying <see cref="IUnitOfWork"/> transaction functionality. It is expected that the <see cref="IEventPublisher"/> implementation
/// uses the same <see cref="PostgresDatabase"/> instance to ensure that the transactional outbox functionality works as expected.</remarks>
public IEventPublisher? Outbox { get; } = outbox;
/// <summary>
/// Gets the underlying <see cref="PostgresUnitOfWorkInvoker"/> used to orchestrate the <see cref="IUnitOfWork"/> functionality.
/// </summary>
public PostgresUnitOfWorkInvoker UnitOfWorkInvoker { get; } = invoker ??= PostgresUnitOfWorkInvoker.Default;
/// <inheritdoc/>
/// <remarks>The <see cref="Outbox"/> is required to enable.</remarks>
public bool AreEventsSupported => Outbox is not null;
/// <inheritdoc/>
public IEventQueue Events => Outbox ?? throw new NotSupportedException($"A Transaction {nameof(Outbox)} has not been provided to enable {nameof(Events)}.");
/// <inheritdoc/>
public Task TransactionAsync(Func<CancellationToken, Task> work, CancellationToken cancellationToken = default) => TransactionAsync(Database.DbArgs, work, cancellationToken);
/// <inheritdoc/>
public Task<T> TransactionAsync<T>(Func<CancellationToken, Task<T>> work, CancellationToken cancellationToken = default) => TransactionAsync(Database.DbArgs, work, cancellationToken);
/// <inheritdoc/>
public Task TransactionAsync(IDataArgs args, Func<CancellationToken, Task> work, CancellationToken cancellationToken = default)
=> UnitOfWorkInvoker.InvokeAsync(this, (PostgresDatabaseArgs)args, async (_, _, cancellationToken) => await work(cancellationToken).ConfigureAwait(false), cancellationToken);
/// <inheritdoc/>
public Task<T> TransactionAsync<T>(IDataArgs args, Func<CancellationToken, Task<T>> work, CancellationToken cancellationToken = default)
=> UnitOfWorkInvoker.InvokeAsync(this, (PostgresDatabaseArgs)args, async (_, _, cancellationToken) => await work(cancellationToken).ConfigureAwait(false), cancellationToken);
}