diff --git a/docs/events/projections/event-projections.md b/docs/events/projections/event-projections.md index dbfc17a..973d7e2 100644 --- a/docs/events/projections/event-projections.md +++ b/docs/events/projections/event-projections.md @@ -33,6 +33,8 @@ public class AuditLogProjection : EventProjection } ``` +The examples name the event parameter `@event`, but that is not required: Polecat identifies the event argument **by type**. In `Project(IEvent @event, IDocumentOperations ops)`, the `IEvent` parameter is the event regardless of its name (`IDocumentOperations` is an interface and is never treated as the event). You only need a conventional event parameter **name** — `@event`, `event`, `e`, or `ev` — to disambiguate a signature in which more than one parameter could be the event. This is the same rule used by aggregate projections; see [Identifying the Event Parameter](/events/projections/single-stream-projections#identifying-the-event-parameter). + ## Registration ```cs diff --git a/docs/events/projections/single-stream-projections.md b/docs/events/projections/single-stream-projections.md index 57a8f9c..cbb070c 100644 --- a/docs/events/projections/single-stream-projections.md +++ b/docs/events/projections/single-stream-projections.md @@ -66,6 +66,15 @@ public void Apply(IEvent @event) } ``` +## Identifying the Event Parameter + +Notice that the examples above name the event parameter `e` in some methods and `@event` in others — both work. Polecat identifies the event argument of a conventional `Create` / `Apply` / `ShouldDelete` method (and an [event projection](/events/projections/event-projections)'s `Project` / `Transform` methods) **by type, not by name**, using the same rule for every projection type: + +1. A parameter typed `IEvent` is always the event, and `T` is the event type — use this when you need event metadata such as `Timestamp` or `Headers`. +2. Otherwise the single **concrete** parameter that is not an interface (`IQuerySession`, `IDocumentOperations`), not `IEvent`, not `CancellationToken`, and not the aggregate type is the event. + +So `Apply(OrderShipped e)` and `Apply(OrderShipped shipped)` are equivalent — the parameter name is incidental. A conventional event parameter **name** is only consulted to disambiguate an unusual signature in which more than one parameter could be the event; the recognized names are `@event`, `event`, `e`, and `ev`. + ## Live Aggregation Use a single stream projection for on-demand replay without persisting: diff --git a/docs/migration-guide.md b/docs/migration-guide.md index 5e5ffd6..45d67a1 100644 --- a/docs/migration-guide.md +++ b/docs/migration-guide.md @@ -230,6 +230,8 @@ public partial class Quest } ``` +The event argument of those conventional methods is identified **by type, not by parameter name**: a parameter typed `IEvent` is the event, otherwise the single concrete parameter that isn't an interface (`IQuerySession` / `IDocumentOperations`), `IEvent`, `CancellationToken`, or the aggregate type. You do **not** need to name it `@event` — `Apply(MembersJoined e)` and `Apply(MembersJoined joined)` are equivalent. A conventional name (`@event`, `event`, `e`, or `ev`) is only consulted to disambiguate a signature with more than one candidate parameter. See [Identifying the Event Parameter](/events/projections/single-stream-projections#identifying-the-event-parameter). + Aggregate identity discovery follows the same convention rule as Marten — by default, the SG looks for a property literally named `Id` (or `Id`). If your aggregate's identity uses a different member name, annotate that member with `[Identity]` from **`JasperFx`** (the same `JasperFx.IdentityAttribute` Polecat uses for document identity — see the [rc dedup-wave relocations](#rc-dedup-wave-relocations) table; it moved out of `Polecat.Attributes` in [#135](https://github.com/JasperFx/polecat/issues/135)): ```csharp