Closed bartelink closed 2 years ago
(Not adding the following goldplated validation logic for now, (which I have implemented and used with success elsewhere) in the interest of not drowning the reader in trivia)
// Generates a stream id in the canonical `{category}-{aggregateId}` format
public static string ToStreamId(Type streamType, object aggregateId, object? tenantId = null)
{
var tenantPrefix = tenantId == null ? $"{tenantId}_" : "";
if (tenantId != null)
CheckNoEmbeddedDashes(nameof(tenantId), tenantId.ToString()!);
var category = ToStreamPrefix(streamType);
CheckNoEmbeddedDashes(nameof(streamType), category);
// (Out-of-the box, the category projection treats anything before a `-` separator as the category name)
// For this reason, we place the "{tenantId}_" bit (if present) on the right hand side of the '-'
return $"{category}-{tenantPrefix}{aggregateId}";
static void CheckNoEmbeddedDashes(string argName, string value)
{
if (value.IndexOf('-') != -1)
throw new ArgumentException("Stream name components may not include embedded '-' characters.", argName);
}
}
While the exact layout of a streamId is pretty arbitrary, in general it works better to have the tenant to the right of the '-' in the streamId as the default category projection treats anything to the left of the first '-' as the category (while this is configurable, this is the default, so Pit Of Success principles apply)