Releases: eventflow/EventFlow
v0.10.642
- Breaking: Updated NuGet reference
Newtonsoft.Json
to v7.0.1
(up from v6.0.8) - Breaking: Remove the empty constructor from
SingleValueObject<>
- New: Added
SingleValueObjectConverter
to help create clean JSON when
e.g. domain events are serialized - New: Added a protected method
Register(IEventApplier)
to
AggregateRoot<,>
that enables developers to override how events are
applied. Use this to e.g. implement state objects - New: Create
AggregateState<,,>
that developers can use to create aggregate
state objects. CallRegister(...)
with the state object as argument
to redirect events to it - New: Allow
AggregateRoot<,>.Apply(...)
, i.e., methods for applying events,
to beprivate
andprotected
- New: Made
AggregateRoot<,>.Emit(...)
protected and virtual to allow
overrides that e.g. add a standard set of metadata from the aggregate state. - New: Made
AggregateRoot<,>.ApplyEvent(...)
protected and virtual to
allow more custom implementations of applying events to the aggregate root. - Fixed: Updated internal NuGet reference
Dapper
to v1.42 (up from v1.38)
v0.9.580
- Braking:
IEventStore.LoadAllEventsAsync
andIEventStore.LoadAllEvents
now take aGlobalPosition
as an argument instead of along
for the
starting position. TheGlobalPosition
is basically a wrapper around a
string that hides the inner workings of each event store. - New: NuGet package
EventFlow.EventStores.EventStore
that provides
integration to Event Store. Its an initial
version and shouldn't be used in production.
v0.8.560
-
Breaking: Remove all functionality related to global sequence
numbers as it proved problematic to maintain. It also matches this
quote:Order is only assured per a handler within an aggregate root
boundary. There is no assurance of order between handlers or
between aggregates. Trying to provide those things leads to
the dark side.Greg Young
- If you use a MSSQL read store, be sure to delete the
LastGlobalSequenceNumber
column during update, or set it to
defaultNULL
IDomainEvent.GlobalSequenceNumber
removedIEventStore.LoadEventsAsync
andIEventStore.LoadEvents
taking
aGlobalSequenceNumberRange
removed
- If you use a MSSQL read store, be sure to delete the
-
Breaking: Remove the concept of event caches. If you really need this
then implement it by registering a decorator forIEventStore
-
Breaking: Moved
IDomainEvent.BatchId
to metadata and created
MetadataKeys.BatchId
to help access it -
New:
IEventStore.DeleteAggregateAsync
to delete an entire aggregate
stream. Please consider carefully if you really want to use it. Storage
might be cheaper than the historic knowledge within your events -
New:
IReadModelPopulator
is new and enables you to both purge and
populate read models by going though the entire event store. Currently
its only basic functionality, but more will be added -
New:
IEventStore
now hasLoadAllEventsAsync
andLoadAllEvents
that
enables you to load all events in the event store a few at a time. -
New:
IMetadata.TimestampEpoch
contains the Unix timestamp version
ofIMetadata.Timestamp
. Also, an additional metadata key
timestamp_epoch
is added to events containing the same data. Note,
theTimestampEpoch
onIMetadata
handles cases in which the
timestamp_epoch
is not present by using the existing timestamp -
Fixed:
AggregateRoot<>
now reads the aggregate version from
domain events applied during aggregate load. This resolves an issue
for when anIEventUpgrader
removed events from the event stream -
Fixed:
InMemoryReadModelStore<,>
is now thread safe
v0.7.481
- New: EventFlow now includes a
IQueryProcessor
that enables you to implement
queries and query handlers in a structure manner. EventFlow ships with two
ready-to-use queries and related handlersReadModelByIdQuery<TReadModel>
: Supported by in-memory and MSSQL read
model storesInMemoryQuery<TReadModel>
: Only supported by in-memory read model store,
but lets you search for any read model based on aPredicate<TReadModel>
v0.6.456
- Breaking: Read models have been significantly improved as they can now
subscribe to events from multiple aggregates. Use a custom
IReadModelLocator
to define how read models are located. The supplied
ILocateByAggregateId
simply uses the aggregate ID. To subscribe
to other events, simply implementIAmReadModelFor<,,>
and make sure
you have supplied a proper read model locator.UseMssqlReadModel
signature changed, change to
.UseMssqlReadModel<MyReadModel, ILocateByAggregateId>()
in
order to have the previous functionalityUseInMemoryReadStoreFor
signature changed, change to
.UseInMemoryReadStoreFor<MyReadModel, ILocateByAggregateId>()
in
order to have the previous functionality
- Breaking: A warning is no longer logged if you forgot to subscribe to
a aggregate event in your read model as read models are no longer
strongly coupled to a specific aggregate and its events - Breaking:
ITransientFaultHandler
now takes the strategy as a generic
argument instead of theUse<>
method. If you want to configure the
retry strategy, useConfigureRetryStrategy(...)
instead - New: You can now have multiple
IReadStoreManager
if you would like to
implement your own read model handling - New:
IEventStore
now has aLoadEventsAsync
andLoadEvents
that loadsIDomainEvent
s based on global sequence number range - New: Its now possible to register generic services without them being
constructed generic types, i.e., registertypeof(IMyService<>)
as
typeof(MyService<>)
- New: Table names for MSSQL read models can be assigned using the
TableAttribute
fromSystem.ComponentModel.DataAnnotations
- Fixed: Subscribers are invoked after read stores have been updated,
which ensures that subscribers can use any read models that were
updated
v0.5.390
- POTENTIAL DATA LOSS for files event store: Files event store now
stores its log as JSON instead of anint
in the form
{"GlobalSequenceNumber":2}
. So rename the current file and put in the
global sequence number before startup - Breaking: Major changes has been made regarding how the aggregate
identity is implemented and referenced through interfaces. These changes makes
it possible to access the identity type directly though all interface. Some
notable examples are listed here. Note that this has NO impact on how data
is stored!IAggregateRoot
changed toIAggregateRoot<TIdentity>
ICommand<TAggregate>
changed toICommand<TAggregate,TIdentity>
ICommandHandler<TAggregate,TCommand>
changed to
ICommandHandler<TAggregate,TIdentity, TCommand>
IAmReadModelFor<TEvent>
changed to
IAmReadModelFor<TAggregate,TIdentity,TEvent>
IDomainEvent<TEvent>
changed toIDomainEvent<TAggregate,TIdentity>
- New:
ICommandBus.Publish
now takes aCancellationToken
argument - Fixed: MSSQL should list columns to SELECT when fetching events
v0.4.353
- Breaking:
ValueObject
now uses public properties instead of both
private and public fields - Breaking: Aggregate IDs are no longer
string
but objects implementing
IIdentity
- Breaking: MSSQL transient exceptions are now retried
- Breaking: All methods on
IMsSqlConnection
has an extraLabel
argument - New:
ITransientFaultHandler
added along with default retry strategies
for optimistic concurrency and MSSQL transient exceptions - New: Release notes added to NuGet packages
- New: Better logging and more descriptive exceptions
- Fixed: Unchecked missing in
ValueObject
when claculating hash - Fixed:
NullReferenceException
thrown ifnull
was stored
inSingleValueObject
andToString()
was called