Skip to content

Commit e301a94

Browse files
authored
V4.3.0/di additions (#38)
🦺 guard against null value for services 📦 updated NuGet package definition ✨ support for System.Text.Json and Newtonsof.Json with Microsoft Dependency Injection ✅ complementary unit tests for JSON marshallers ✅ complementary unit tests for NATS ⚗️ support for github copilot instructions ⬆️ bump dependencies 💬 updated community health pages 📝 updated DocFX
1 parent 1f70381 commit e301a94

103 files changed

Lines changed: 1310 additions & 42 deletions

File tree

Some content is hidden

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

.docfx/docfx.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,11 @@
3737
"Savvyio.Extensions.DependencyInjection.EFCore.Domain/**.csproj",
3838
"Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/**.csproj",
3939
"Savvyio.Extensions.DependencyInjection.NATS/**.csproj",
40+
"Savvyio.Extensions.DependencyInjection.Newtonsoft.Json/**.csproj",
4041
"Savvyio.Extensions.DependencyInjection.QueueStorage/**.csproj",
4142
"Savvyio.Extensions.DependencyInjection.RabbitMQ/**.csproj",
4243
"Savvyio.Extensions.DependencyInjection.SimpleQueueService/**.csproj",
44+
"Savvyio.Extensions.DependencyInjection.Text.Json/**.csproj",
4345
"Savvyio.Extensions.Dispatchers/**.csproj",
4446
"Savvyio.Extensions.EFCore/**.csproj",
4547
"Savvyio.Extensions.EFCore.Domain/**.csproj",

.github/copilot-instructions.md

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
---
2+
description: 'Writing Unit Tests in Savvyio'
3+
applyTo: "**/*.{cs,csproj}"
4+
---
5+
6+
# Writing Unit Tests in Savvyio
7+
8+
This document provides instructions for writing unit tests in the Savvyio codebase. Please follow these guidelines to ensure consistency and maintainability.
9+
10+
---
11+
12+
## 1. Base Class
13+
14+
**Always inherit from the `Test` base class** for all unit test classes.
15+
This ensures consistent setup, teardown, and output handling across all tests.
16+
17+
```csharp
18+
using Codebelt.Extensions.Xunit;
19+
using Xunit;
20+
using Xunit.Abstractions;
21+
22+
namespace Your.Namespace
23+
{
24+
public class YourTestClass : Test
25+
{
26+
public YourTestClass(ITestOutputHelper output) : base(output)
27+
{
28+
}
29+
30+
// Your tests here
31+
}
32+
}
33+
```
34+
35+
---
36+
37+
## 2. Test Method Attributes
38+
39+
- Use `[Fact]` for standard unit tests.
40+
- Use `[Theory]` with `[InlineData]` or other data sources for parameterized tests.
41+
42+
---
43+
44+
## 3. Naming Conventions
45+
46+
- **Test classes**: End with `Test` (e.g., `CommandDispatcherTest`).
47+
- **Test methods**: Use descriptive names that state the expected behavior (e.g., `ShouldReturnTrue_WhenConditionIsMet`).
48+
49+
---
50+
51+
## 4. Assertions
52+
53+
- Use `Assert` methods from xUnit for all assertions.
54+
- Prefer explicit and expressive assertions (e.g., `Assert.Equal`, `Assert.NotNull`, `Assert.Contains`).
55+
56+
---
57+
58+
## 5. File and Namespace Organization
59+
60+
- Place test files in the appropriate test project and folder structure.
61+
- Use namespaces that mirror the source code structure.
62+
- The unit tests for the Savvyio.Foo assembly live in the Savvyio.Foo.Tests assembly.
63+
- The functional tests for the Savvyio.Foo assembly live in the Savvyio.Foo.FunctionalTests assembly.
64+
- Test class names end with Test and live in the same namespace as the class being tested, e.g., the unit tests for the Boo class that resides in the Savvyio.Foo assembly would be named BooTest and placed in the Savvyio.Foo namespace in the Savvyio.Foo.Tests assembly.
65+
- Modify the associated .csproj file to override the root namespace, e.g., <RootNamespace>Savvyio.Foo</RootNamespace>.
66+
67+
---
68+
69+
## 6. Example Test
70+
71+
```csharp
72+
using Codebelt.Extensions.Xunit;
73+
using Xunit;
74+
using Xunit.Abstractions;
75+
76+
namespace Savvyio.Commands
77+
{
78+
/// <summary>
79+
/// Tests for the <see cref="DefaultCommand"/> class.
80+
/// </summary>
81+
public class CommandTest : Test
82+
{
83+
public CommandTest(ITestOutputHelper output) : base(output)
84+
{
85+
}
86+
87+
[Fact]
88+
public void DefaultCommand_Ensure_Initialization_Defaults()
89+
{
90+
var sut = new DefaultCommand();
91+
92+
Assert.IsAssignableFrom<Command>(sut);
93+
Assert.IsAssignableFrom<ICommand>(sut);
94+
Assert.IsAssignableFrom<Request>(sut);
95+
Assert.IsAssignableFrom<IRequest>(sut);
96+
Assert.IsAssignableFrom<IMetadata>(sut);
97+
Assert.Contains(sut.Metadata, pair => pair.Key == MetadataDictionary.CorrelationId);
98+
}
99+
}
100+
}
101+
```
102+
103+
---
104+
105+
## 7. Additional Guidelines
106+
107+
- Keep tests focused and isolated.
108+
- Do not rely on external systems except for xUnit itself and Codebelt.Extensions.Xunit (and derived from this).
109+
- Ensure tests are deterministic and repeatable.
110+
111+
---
112+
113+
For further examples, refer to existing test files such as
114+
[`test/Savvyio.Commands.Tests/CommandDispatcherTest.cs`](test/Savvyio.Commands.Tests/CommandDispatcherTest.cs)
115+
and
116+
[`test/Savvyio.Commands.Tests/CommandTest.cs`](test/Savvyio.Commands.Tests/CommandTest.cs).
117+
118+
---
119+
description: 'Writing XML documentation in Savvyio'
120+
applyTo: "**/*.cs"
121+
---
122+
123+
# Writing XML documentation in Savvyio
124+
125+
This document provides instructions for writing XML documentation.
126+
127+
---
128+
129+
## 1. Documentation Style
130+
131+
- Use the same documentation style as found throughout the codebase.
132+
- Add XML doc comments to public and protected classes and methods where appropriate.
133+
- Example:
134+
135+
```csharp
136+
using Cuemon.Extensions.DependencyInjection;
137+
using Cuemon.Extensions.Text.Json.Formatters;
138+
using Microsoft.Extensions.DependencyInjection;
139+
using System;
140+
using Cuemon;
141+
using Savvyio.Extensions.Text.Json;
142+
143+
namespace Savvyio.Extensions.DependencyInjection.Text.Json
144+
{
145+
/// <summary>
146+
/// Extension methods for the <see cref="IServiceCollection"/> interface.
147+
/// </summary>
148+
public static class ServiceCollectionExtensions
149+
{
150+
/// <summary>
151+
/// Adds an <see cref="JsonMarshaller" /> implementation to the specified <see cref="IServiceCollection" />.
152+
/// </summary>
153+
/// <param name="services">The <see cref="IServiceCollection"/> to extend.</param>
154+
/// <param name="jsonSetup">The <see cref="JsonFormatterOptions" /> which may be configured. Default is optimized for messaging.</param>
155+
/// <param name="serviceSetup">The <see cref="ServiceOptions" /> which may be configured. Default is <see cref="ServiceLifetime.Singleton"/>.</param>
156+
/// <returns>A reference to <paramref name="services"/> so that additional calls can be chained.</returns>
157+
/// <remarks>The implementation will be type forwarded accordingly.</remarks>
158+
/// <exception cref="ArgumentNullException">
159+
/// <paramref name="services"/> cannot be null.
160+
/// </exception>
161+
public static IServiceCollection AddJsonMarshaller(this IServiceCollection services, Action<JsonFormatterOptions> jsonSetup = null, Action<ServiceOptions> serviceSetup = null)
162+
{
163+
Validator.ThrowIfNull(services);
164+
return services
165+
.AddMarshaller<JsonMarshaller>(serviceSetup)
166+
.AddConfiguredOptions(jsonSetup ?? (o => o.Settings.WriteIndented = false));
167+
}
168+
}
169+
}
170+
171+
172+
using System;
173+
using Cuemon;
174+
using Cuemon.Configuration;
175+
176+
namespace Savvyio.Extensions.NATS
177+
{
178+
/// <summary>
179+
/// Configuration options that is related to NATS.
180+
/// </summary>
181+
/// <seealso cref="IValidatableParameterObject" />
182+
public class NatsMessageOptions : IValidatableParameterObject
183+
{
184+
/// <summary>
185+
/// Initializes a new instance of the <see cref="NatsMessageOptions"/> class with default values.
186+
/// </summary>
187+
/// <remarks>
188+
/// The following table shows the initial property values for an instance of <see cref="NatsMessageOptions"/>.
189+
/// <list type="table">
190+
/// <listheader>
191+
/// <term>Property</term>
192+
/// <description>Initial Value</description>
193+
/// </listheader>
194+
/// <item>
195+
/// <term><see cref="NatsUrl"/></term>
196+
/// <description><c>new Uri("nats://127.0.0.1:4222")</c></description>
197+
/// </item>
198+
/// <item>
199+
/// <term><see cref="Subject"/></term>
200+
/// <description><c>null</c></description>
201+
/// </item>
202+
/// </list>
203+
/// </remarks>
204+
public NatsMessageOptions()
205+
{
206+
NatsUrl = new Uri("nats://127.0.0.1:4222");
207+
}
208+
209+
/// <summary>
210+
/// Gets or sets the URI of the NATS server.
211+
/// </summary>
212+
public Uri NatsUrl { get; set; }
213+
214+
/// <summary>
215+
/// Gets or sets the subject to publish or subscribe to in NATS.
216+
/// </summary>
217+
public string Subject { get; set; }
218+
219+
/// <summary>
220+
/// Validates the current options and throws an exception if the state is invalid.
221+
/// </summary>
222+
/// <exception cref="InvalidOperationException">
223+
/// <see cref="Subject"/> is null or whitespace - or -
224+
/// <see cref="NatsUrl"/> is null.
225+
/// </exception>
226+
public virtual void ValidateOptions()
227+
{
228+
Validator.ThrowIfInvalidState(NatsUrl == null);
229+
Validator.ThrowIfInvalidState(string.IsNullOrWhiteSpace(Subject));
230+
}
231+
}
232+
}
233+
234+
```

.nuget/Savvyio.App/PackageReleaseNotes.txt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,37 @@
1+
Version: 4.3.0
2+
Availability: .NET 9 and .NET 8
3+
 
4+
# References
5+
- Savvyio
6+
- Savvyio.Commands
7+
- Savvyio.Commands.Messaging
8+
- Savvyio.Domain
9+
- Savvyio.Domain.EventSourcing
10+
- Savvyio.EventDriven
11+
- Savvyio.EventDriven.Messaging
12+
- Savvyio.Extensions.Dapper
13+
- Savvyio.Extensions.DependencyInjection
14+
- Savvyio.Extensions.DependencyInjection.Dapper
15+
- Savvyio.Extensions.DependencyInjection.Domain
16+
- Savvyio.Extensions.DependencyInjection.EFCore
17+
- Savvyio.Extensions.DependencyInjection.EFCore.Domain
18+
- Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing
19+
- Savvyio.Extensions.DependencyInjection.NATS
20+
- Savvyio.Extensions.DependencyInjection.QueueStorage
21+
- Savvyio.Extensions.DependencyInjection.RabbitMQ
22+
- Savvyio.Extensions.DependencyInjection.SimpleQueueService
23+
- Savvyio.Extensions.Dispatchers
24+
- Savvyio.Extensions.EFCore
25+
- Savvyio.Extensions.EFCore.Domain
26+
- Savvyio.Extensions.EFCore.Domain.EventSourcing
27+
- Savvyio.Extensions.NATS
28+
- Savvyio.Extensions.QueueStorage
29+
- Savvyio.Extensions.RabbitMQ
30+
- Savvyio.Extensions.SimpleQueueService
31+
- Savvyio.Extensions.Text.Json
32+
- Savvyio.Messaging
33+
- Savvyio.Queries
34+
 
135
Version: 4.2.0
236
Availability: .NET 9 and .NET 8
337

.nuget/Savvyio.App/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Savvyio.App
22

3-
Provides a complete and convenient set of API additions for building a DDD, CQRS and Event Sourcing enabled .NET application using Microsoft Dependency Injection, Microsoft Entity Framework Core and Dapper.
3+
Provides a complete and convenient set of API additions for building a DDD, CQRS and Event Sourcing enabled .NET application using Microsoft Dependency Injection, Microsoft Entity Framework Core, Dapper, JSON Marshaller, AWS SNS/SQS, Azure Queue Storage/Event Grid, RabbitMQ and NATS.
44

55
## About
66

@@ -30,9 +30,11 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel
3030
* [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦
3131
* [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦
3232
* [Savvyio.Extensions.DependencyInjection.NATS](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.NATS/) 📦
33+
* [Savvyio.Extensions.DependencyInjection.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.Newtonsoft.Json/) 📦
3334
* [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦
3435
* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦
3536
* [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦
37+
* [Savvyio.Extensions.DependencyInjection.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.Text.Json/) 📦
3638
* [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦
3739
* [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦
3840
* [Savvyio.Extensions.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain/) 📦

.nuget/Savvyio.Commands.Messaging/PackageReleaseNotes.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
1+
Version: 4.3.0
2+
Availability: .NET 9 and .NET 8
3+
 
4+
# ALM
5+
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)
6+
 
17
Version: 4.2.0
28
Availability: .NET 9 and .NET 8
39

10+
# ALM
11+
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)
12+
 
413
Version: 4.1.1
514
Availability: .NET 9 and .NET 8
615

.nuget/Savvyio.Commands.Messaging/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel
3030
* [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦
3131
* [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦
3232
* [Savvyio.Extensions.DependencyInjection.NATS](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.NATS/) 📦
33+
* [Savvyio.Extensions.DependencyInjection.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.Newtonsoft.Json/) 📦
3334
* [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦
3435
* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦
3536
* [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦
37+
* [Savvyio.Extensions.DependencyInjection.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.Text.Json/) 📦
3638
* [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦
3739
* [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦
3840
* [Savvyio.Extensions.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain/) 📦

.nuget/Savvyio.Commands/PackageReleaseNotes.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
Version: 4.3.0
2+
Availability: .NET 9 and .NET 8
3+
 
4+
# ALM
5+
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)
6+
 
17
Version: 4.2.0
28
Availability: .NET 9 and .NET 8
39

.nuget/Savvyio.Commands/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel
3030
* [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦
3131
* [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦
3232
* [Savvyio.Extensions.DependencyInjection.NATS](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.NATS/) 📦
33+
* [Savvyio.Extensions.DependencyInjection.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.Newtonsoft.Json/) 📦
3334
* [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦
3435
* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦
3536
* [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦
37+
* [Savvyio.Extensions.DependencyInjection.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.Text.Json/) 📦
3638
* [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦
3739
* [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦
3840
* [Savvyio.Extensions.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain/) 📦

.nuget/Savvyio.Core/PackageReleaseNotes.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
Version: 4.3.0
2+
Availability: .NET 9 and .NET 8
3+
 
4+
# ALM
5+
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)
6+
 
17
Version: 4.2.0
28
Availability: .NET 9 and .NET 8
39

.nuget/Savvyio.Core/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@ It is, by heart, free, flexible and built to extend and boost your agile codebel
3030
* [Savvyio.Extensions.DependencyInjection.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain/) 📦
3131
* [Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing/) 📦
3232
* [Savvyio.Extensions.DependencyInjection.NATS](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.NATS/) 📦
33+
* [Savvyio.Extensions.DependencyInjection.Newtonsoft.Json](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.Newtonsoft.Json/) 📦
3334
* [Savvyio.Extensions.DependencyInjection.QueueStorage](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.QueueStorage/) 📦
3435
* [Savvyio.Extensions.DependencyInjection.RabbitMQ](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.RabbitMQ/) 📦
3536
* [Savvyio.Extensions.DependencyInjection.SimpleQueueService](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.SimpleQueueService/) 📦
37+
* [Savvyio.Extensions.DependencyInjection.Text.Json](https://www.nuget.org/packages/Savvyio.Extensions.DependencyInjection.Text.Json/) 📦
3638
* [Savvyio.Extensions.Dispatchers](https://www.nuget.org/packages/Savvyio.Extensions.Dispatchers/) 📦
3739
* [Savvyio.Extensions.EFCore](https://www.nuget.org/packages/Savvyio.Extensions.EFCore/) 📦
3840
* [Savvyio.Extensions.EFCore.Domain](https://www.nuget.org/packages/Savvyio.Extensions.EFCore.Domain/) 📦

0 commit comments

Comments
 (0)