You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit ffb488e
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: docs/coding-and-design-guidelines.md
+17Lines changed: 17 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -40,6 +40,23 @@ There are a few things that are still registered using convention. Note that the
40
40
Additionally, because NServiceBus does a type-scan at startup it will automatically register any implementations of `Feature` and `IHandleMessage<>`. We have chosen to leave this alone as we would be fighting with NServiceBus in order to turn this off.
41
41
42
42
43
+
## Prefer explicit persistence operations
44
+
45
+
Use a direct data-store method when all inputs for a persistence operation fit in one method call. The method should own and dispose its EF Core scope/context or RavenDB session, accept a `CancellationToken`, and commit before returning. Returned entities are detached snapshots; callers must not be required to mutate tracked entities as an implicit persistence command.
46
+
47
+
Atomic operations that can encounter concurrency conflicts should document their provider guarantees and translate expected provider exceptions into explicit domain outcomes. For example, a unique-key or optimistic-concurrency conflict should not escape when contention is part of the operation's normal contract.
48
+
49
+
Reserve a specialized unit of work for cases where a caller genuinely composes several writes into one atomic batch. New unit-of-work APIs should consistently provide:
50
+
51
+
- an `I...UnitOfWorkFactory`;
52
+
- a `StartNew` factory method;
53
+
- a `Complete(CancellationToken)` commit method;
54
+
-`IAsyncDisposable` lifetime ownership;
55
+
- explicit operation-recording methods rather than mutation of tracked return values;
56
+
- documented commit, abandon, repeated-completion, and concurrency behavior.
57
+
58
+
Do not introduce generic `IDataSessionManager`-style abstractions or persistence managers with hidden call-order protocols. During review, prefer one explicit store operation unless caller-composed atomicity requires a unit of work.
59
+
43
60
## Avoid property injection
44
61
45
62
Although the Autofac container can be configured to allow property injection, we prefer to avoid it. There is no way to specify property injection using the Microsoft DI abstractions, and the default `IServiceProvider` implementation does not support it. Where possible, use constructor injection instead.
$"{unsavedEndpoints.Length} of {endpointNames.Length} endpoints were not saved when RecordMonitoringThroughput returned: {string.Join(", ",unsavedEndpoints)}");
191
+
Assert.That(endpointsWithoutThroughput,Is.Empty,
192
+
$"{endpointsWithoutThroughput.Length} of {endpointNames.Length} endpoints had no throughput recorded when RecordMonitoringThroughput returned: {string.Join(", ",endpointsWithoutThroughput)}");
193
+
}
194
+
195
+
Assert.That(dataStore.RecordedThroughput.Values,Is.All.EqualTo(15L),"Expected a throughput of 15 for every endpoint");
196
+
}
197
+
198
+
// Records only after suspending, so any write the service starts without awaiting is still
199
+
// outstanding when RecordMonitoringThroughput returns.
if(messageis not null&&message.EndpointThroughputDatais{}endpointThroughputData)
22
22
{
23
-
Debug.WriteLine($"Throughput data from {message.StartDateTime:yyyy-MM-dd HH:mm} to {message.EndDateTime:yyyy-MM-dd HH:mm} for {message.EndpointThroughputData?.Length} endpoint(s)");
23
+
Debug.WriteLine($"Throughput data from {message.StartDateTime:yyyy-MM-dd HH:mm} to {message.EndDateTime:yyyy-MM-dd HH:mm} for {endpointThroughputData.Length} endpoint(s)");
24
24
25
-
message.EndpointThroughputData?.ToList().ForEach(async e =>
0 commit comments