Skip to content

Commit 75c7fa9

Browse files
authored
refactor: ♻️ enhance masstransit messaging registration (#235)
1 parent f5f13fa commit 75c7fa9

File tree

100 files changed

+1415
-826
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+1415
-826
lines changed

src/BuildingBlocks/BuildingBlocks.Abstractions/BuildingBlocks.Abstractions.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
</ItemGroup>
2626

2727
<ItemGroup>
28+
<PackageReference Include="Riok.Mapperly"/>
2829
<PackageReference Include="AutoMapper"/>
2930
<PackageReference Include="MediatR"/>
3031
<PackageReference Include="MongoDB.Driver"/>

src/BuildingBlocks/BuildingBlocks.Abstractions/Domain/AggregateId.cs

+1-4
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,5 @@ protected AggregateId(long value)
3232
return new AggregateId(value);
3333
}
3434

35-
public static implicit operator long(AggregateId id)
36-
{
37-
return id.Value;
38-
}
35+
public static implicit operator long(AggregateId? id) => id?.Value ?? default;
3936
}
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,26 @@
11
namespace BuildingBlocks.Abstractions.Events;
22

3-
public interface IEventEnvelopeMetadata
3+
public record EventEnvelopeMetadata(
4+
Guid MessageId,
5+
Guid CorrelationId,
6+
string MessageType,
7+
string Name,
8+
// Causation ID identifies messages that cause other messages to be published. In simple terms, it's used to see what causes what. The first message in a message conversation typically doesn't have a causation ID. Downstream messages get their causation IDs by copying message IDs from messages, causing downstream messages to be published
9+
Guid? CausationId
10+
)
411
{
5-
Guid MessageId { get; init; }
6-
string MessageType { get; init; }
7-
string Name { get; init; }
8-
Guid? CausationId { get; init; }
9-
Guid CorrelationId { get; init; }
10-
DateTime Created { get; init; }
11-
long? CreatedUnixTime { get; init; }
12-
IDictionary<string, object?> Headers { get; init; }
12+
public IDictionary<string, object?> Headers { get; init; } = new Dictionary<string, object?>();
13+
public DateTime Created { get; init; } = DateTime.Now;
14+
public long? CreatedUnixTime { get; init; } = DateTimeHelper.ToUnixTimeSecond(DateTime.Now);
15+
16+
internal static class DateTimeHelper
17+
{
18+
private static readonly DateTime _epoch = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
19+
20+
public static long ToUnixTimeSecond(DateTime datetime)
21+
{
22+
var unixTime = (datetime.ToUniversalTime() - _epoch).TotalSeconds;
23+
return (long)unixTime;
24+
}
25+
}
1326
}

src/BuildingBlocks/BuildingBlocks.Abstractions/Events/EventEnvelope.cs src/BuildingBlocks/BuildingBlocks.Abstractions/Events/IEventEnvelope.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ namespace BuildingBlocks.Abstractions.Events;
1212
// Ref: https://www.enterpriseintegrationpatterns.com/patterns/messaging/EnvelopeWrapper.html
1313
public interface IEventEnvelope
1414
{
15-
object Data { get; }
16-
IEventEnvelopeMetadata? Metadata { get; }
15+
object Message { get; }
16+
EventEnvelopeMetadata Metadata { get; }
1717
}
1818

1919
public interface IEventEnvelope<out T> : IEventEnvelope
2020
where T : notnull
2121
{
22-
new T Data { get; }
22+
new T Message { get; }
2323
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using BuildingBlocks.Abstractions.Events;
2+
3+
namespace BuildingBlocks.Abstractions.Messaging;
4+
5+
public interface IBusDirectPublisher
6+
{
7+
Task PublishAsync<TMessage>(IEventEnvelope<TMessage> eventEnvelope, CancellationToken cancellationToken = default)
8+
where TMessage : IMessage;
9+
10+
Task PublishAsync(IEventEnvelope eventEnvelope, CancellationToken cancellationToken = default);
11+
12+
public Task PublishAsync<TMessage>(
13+
IEventEnvelope<TMessage> eventEnvelope,
14+
string? exchangeOrTopic = null,
15+
string? queue = null,
16+
CancellationToken cancellationToken = default
17+
)
18+
where TMessage : IMessage;
19+
20+
public Task PublishAsync(
21+
IEventEnvelope eventEnvelope,
22+
string? exchangeOrTopic = null,
23+
string? queue = null,
24+
CancellationToken cancellationToken = default
25+
);
26+
}

src/BuildingBlocks/BuildingBlocks.Abstractions/Messaging/IBusProducer.cs

-18
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using BuildingBlocks.Abstractions.Events;
2+
3+
namespace BuildingBlocks.Abstractions.Messaging;
4+
5+
public interface IBusPublisher
6+
{
7+
public Task PublishAsync<TMessage>(TMessage message, CancellationToken cancellationToken = default)
8+
where TMessage : IMessage;
9+
10+
Task PublishAsync<TMessage>(IEventEnvelope<TMessage> eventEnvelope, CancellationToken cancellationToken = default)
11+
where TMessage : IMessage;
12+
13+
public Task PublishAsync<TMessage>(
14+
TMessage message,
15+
string? exchangeOrTopic = null,
16+
string? queue = null,
17+
CancellationToken cancellationToken = default
18+
)
19+
where TMessage : IMessage;
20+
21+
public Task PublishAsync<TMessage>(
22+
IEventEnvelope<TMessage> eventEnvelope,
23+
string? exchangeOrTopic = null,
24+
string? queue = null,
25+
CancellationToken cancellationToken = default
26+
)
27+
where TMessage : IMessage;
28+
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
namespace BuildingBlocks.Abstractions.Messaging;
22

3-
public interface IExternalEventBus : IBusProducer, IBusConsumer;
3+
public interface IExternalEventBus : IBusPublisher, IBusConsumer;

src/BuildingBlocks/BuildingBlocks.Abstractions/Messaging/PersistMessage/IMessagePersistenceService.cs

+6-13
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,23 @@ Task<IReadOnlyList<StoreMessage>> GetByFilterAsync(
2020
CancellationToken cancellationToken = default
2121
);
2222

23-
Task AddPublishMessageAsync<TEventEnvelope>(
24-
TEventEnvelope eventEnvelope,
23+
Task AddPublishMessageAsync<TMessage>(
24+
IEventEnvelope<TMessage> eventEnvelope,
2525
CancellationToken cancellationToken = default
2626
)
27-
where TEventEnvelope : IEventEnvelope;
28-
29-
Task AddPublishMessageAsync<TEventEnvelope, TMessage>(
30-
TEventEnvelope eventEnvelope,
31-
CancellationToken cancellationToken = default
32-
)
33-
where TEventEnvelope : IEventEnvelope<TMessage>
3427
where TMessage : IMessage;
3528

36-
Task AddReceivedMessageAsync<TMessageEnvelope>(
37-
TMessageEnvelope messageEnvelope,
29+
Task AddReceivedMessageAsync<TMessage>(
30+
IEventEnvelope<TMessage> eventEnvelope,
3831
CancellationToken cancellationToken = default
3932
)
40-
where TMessageEnvelope : IEventEnvelope;
33+
where TMessage : IMessage;
4134

4235
Task AddInternalMessageAsync<TInternalCommand>(
4336
TInternalCommand internalCommand,
4437
CancellationToken cancellationToken = default
4538
)
46-
where TInternalCommand : class, IInternalCommand;
39+
where TInternalCommand : IInternalCommand;
4740

4841
Task AddNotificationAsync<TDomainNotification>(
4942
TDomainNotification notification,

src/BuildingBlocks/BuildingBlocks.Abstractions/Serialization/IMessageSerilizer.cs

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using BuildingBlocks.Abstractions.Events;
2+
using BuildingBlocks.Abstractions.Messaging;
23

34
namespace BuildingBlocks.Abstractions.Serialization;
45

@@ -12,12 +13,23 @@ public interface IMessageSerializer
1213
/// <param name="eventEnvelope">a messageEnvelope that implement IMessage interface.</param>
1314
/// <returns>a json string for serialized messageEnvelope.</returns>
1415
string Serialize(IEventEnvelope eventEnvelope);
16+
string Serialize<T>(IEventEnvelope<T> eventEnvelope)
17+
where T : IMessage;
1518

1619
/// <summary>
1720
/// Deserialize the given payload into a <see cref="IEventEnvelope" />.
1821
/// </summary>
1922
/// <param name="eventEnvelope">a json data to deserialize to a messageEnvelope.</param>
23+
/// <param name="messageType">the type of message inside event-envelope.</param>
2024
/// <returns>return a messageEnvelope type.</returns>
21-
IEventEnvelope? Deserialize(string eventEnvelope);
2225
IEventEnvelope? Deserialize(string eventEnvelope, Type messageType);
26+
27+
/// <summary>
28+
/// Deserialize the given payload into a IEventEnvelope" />.
29+
/// </summary>
30+
/// <param name="eventEnvelope"></param>
31+
/// <typeparam name="T"></typeparam>
32+
/// <returns></returns>
33+
IEventEnvelope<T>? Deserialize<T>(string eventEnvelope)
34+
where T : IMessage;
2335
}

src/BuildingBlocks/BuildingBlocks.Core/Domain/AuditAggregate.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ public abstract class AuditAggregate<TId> : Aggregate<TId>, IAuditableEntity<TId
99
}
1010

1111
public abstract class AuditAggregate<TIdentity, TId> : AuditAggregate<TIdentity>
12-
where TIdentity : Identity<TId> { }
12+
where TIdentity : Identity<TId>;
1313

14-
public abstract class AuditAggregate : AuditAggregate<Identity<long>, long> { }
14+
public abstract class AuditAggregate : AuditAggregate<Identity<long>, long>;

src/BuildingBlocks/BuildingBlocks.Core/Domain/AuditableEntity.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ namespace BuildingBlocks.Core.Domain;
44

55
public class AuditableEntity<TId> : Entity<TId>, IAuditableEntity<TId>
66
{
7-
public DateTime? LastModified { get; protected set; } = default!;
8-
public int? LastModifiedBy { get; protected set; } = default!;
7+
public DateTime? LastModified { get; init; } = default!;
8+
public int? LastModifiedBy { get; init; } = default!;
99
}
1010

1111
public abstract class AuditableEntity<TIdentity, TId> : AuditableEntity<TIdentity>
12-
where TIdentity : Identity<TId> { }
12+
where TIdentity : Identity<TId>;
1313

14-
public class AuditableEntity : AuditableEntity<Identity<long>, long> { }
14+
public class AuditableEntity : AuditableEntity<Identity<long>, long>;

src/BuildingBlocks/BuildingBlocks.Core/Domain/Entity.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ namespace BuildingBlocks.Core.Domain;
44

55
public abstract class Entity<TId> : IEntity<TId>
66
{
7-
public TId Id { get; protected set; } = default!;
8-
public DateTime Created { get; private set; } = default!;
9-
public int? CreatedBy { get; private set; } = default!;
7+
public TId Id { get; init; } = default!;
8+
public DateTime Created { get; init; } = default!;
9+
public int? CreatedBy { get; init; } = default!;
1010
}
1111

1212
public abstract class Entity<TIdentity, TId> : Entity<TIdentity>
13-
where TIdentity : Identity<TId> { }
13+
where TIdentity : Identity<TId>;
1414

15-
public abstract class Entity : Entity<EntityId, long>, IEntity { }
15+
public abstract class Entity : Entity<EntityId, long>, IEntity;

src/BuildingBlocks/BuildingBlocks.Core/Domain/ValueObjects/Address.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,5 @@ public PostalCode() { }
5555
// validations should be placed here instead of constructor
5656
public static PostalCode Of(string? postalCode) => new() { Value = postalCode.NotBeNullOrWhiteSpace() };
5757

58-
public static implicit operator string(PostalCode postalCode) => postalCode.Value;
58+
public static implicit operator string(PostalCode? postalCode) => postalCode?.Value ?? string.Empty;
5959
}

src/BuildingBlocks/BuildingBlocks.Core/Domain/ValueObjects/Amount.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public static Amount Of([NotNull] decimal? value)
2929
return Of(value.Value);
3030
}
3131

32-
public static Amount Of(decimal value)
32+
public static Amount Of([NotNull] decimal value)
3333
{
3434
value.NotBeNegativeOrZero();
3535

@@ -42,7 +42,7 @@ public static Amount Of(decimal value)
4242
return new Amount(value);
4343
}
4444

45-
public static implicit operator decimal(Amount value) => value.Value;
45+
public static implicit operator decimal(Amount? value) => value?.Value ?? default;
4646

4747
public static bool operator >(Amount a, Amount b) => a.Value > b.Value;
4848

src/BuildingBlocks/BuildingBlocks.Core/Domain/ValueObjects/BirthDate.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public static BirthDate Of(DateTime value)
4141
return new BirthDate { Value = value };
4242
}
4343

44-
public static implicit operator DateTime(BirthDate value) => value.Value;
44+
public static implicit operator DateTime(BirthDate? value) => value?.Value ?? default;
4545

4646
// https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/functional/deconstruct#user-defined-types
4747
// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record#positional-syntax-for-property-definition

src/BuildingBlocks/BuildingBlocks.Core/Domain/ValueObjects/Currency.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public static Currency Of([NotNull] string? value)
2828
return new Currency(value);
2929
}
3030

31-
public static implicit operator string(Currency value) => value.Value;
31+
public static implicit operator string(Currency? value) => value?.Value ?? string.Empty;
3232

3333
// https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/functional/deconstruct#user-defined-types
3434
// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record#positional-syntax-for-property-definition

src/BuildingBlocks/BuildingBlocks.Core/Domain/ValueObjects/Email.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public static Email Of([NotNull] string? value)
2929
return new Email(value);
3030
}
3131

32-
public static implicit operator string(Email value) => value.Value;
32+
public static implicit operator string(Email? value) => value?.Value ?? string.Empty;
3333

3434
// https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/functional/deconstruct#user-defined-types
3535
// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record#positional-syntax-for-property-definition

src/BuildingBlocks/BuildingBlocks.Core/Domain/ValueObjects/MobileNumber.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public static MobileNumber Of([NotNull] string? value)
2727
return new MobileNumber(value);
2828
}
2929

30-
public static implicit operator string(MobileNumber phoneNumber) => phoneNumber.Value;
30+
public static implicit operator string(MobileNumber? phoneNumber) => phoneNumber?.Value ?? string.Empty;
3131

3232
// https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/functional/deconstruct#user-defined-types
3333
// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record#positional-syntax-for-property-definition

src/BuildingBlocks/BuildingBlocks.Core/Domain/ValueObjects/PhoneNumber.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public static PhoneNumber Of([NotNull] string? value)
2727
return new PhoneNumber(value);
2828
}
2929

30-
public static implicit operator string(PhoneNumber phoneNumber) => phoneNumber.Value;
30+
public static implicit operator string(PhoneNumber? phoneNumber) => phoneNumber?.Value ?? string.Empty;
3131

3232
// https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/functional/deconstruct#user-defined-types
3333
// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record#positional-syntax-for-property-definition

0 commit comments

Comments
 (0)