Releases: eventflow/EventFlow
Releases · eventflow/EventFlow
v0.20.1274
- Breaking:
Entity<T>
now inherits fromValueObject
but uses only theId
field as equality component. OverrideGetEqualityComponents()
if you have
a different notion of equality for a specific entity - Breaking:
Entity<T>
will now throw anArgumentNullException
if theid
passed to its constructor isnull
- Breaking: Fixed method spelling. Renamed
ISpecification<T>.WhyIsNotStatisfiedBy
toWhyIsNotSatisfiedBy
and
Specification<T>.IsNotStatisfiedBecause
toIsNotSatisfiedBecause
- New: Read model support for Elasticsearch via the new NuGet package
EventFlow.ReadStores.Elasticsearch
v0.19.1225
- Breaking:
AddDefaults
now also adds the job type definition to the
IJobsDefinitonService
- New: Implemented a basic specification pattern by providing
ISpecification<T>
, an easy-to-useSpecificaion<T>
and a set of extension
methods. Look at the EventFlow specification tests to get started - Fixed:
IEventDefinitionService
,ICommandDefinitonService
and
IJobsDefinitonService
now longer throw an exception if an existing
event is loaded, i.e., multiple calls toAddEvents(...)
,AddCommand(...)
andAddJobs(...)
no longer throws an exception - Fixed:
DomainError.With(...)
no longer executesstring.format
if only
one argument is parsed
v0.18.1181
- POTENTIAL DATA LOSS for the files event store: The EventFlow
internal functionality regarding event stores has been refactored resulting
in information regarding aggregate names being removed from the event
persistence layer. The files based event store no longer stores its events in
the path[STORE PATH]\[AGGREGATE NAME]\[AGGREGATE ID]\[SEQUENCE].json
, but
in the path[STORE PATH]\[AGGREGATE ID]\[SEQUENCE].json
. Thus if you are
using the files event store for tests, you should move the events into the
new file structure. Alternatively, implement the newIFilesEventLocator
and
provide your own custom event file layout. - Breaking: Event stores have been split into two parts, the
IEventStore
and the newIEventPersistence
.IEventStore
has the same interface before
but the implementation is now no longer responsible for persisting the events,
only converting and serializing the persisted events.IEventPersistence
handles the actual storing of events and thus if any custom event stores have
been implemented, they should implement to the newIEventPersistence
instead. - New: Added
IEntity
,IEntity<>
and an optionalEntity<>
that developers
can use to implement DDD entities.
v0.17.1134
- Fixed: Using NuGet package
EventFlow.Autofac
causes an exception with the
messageThe type 'EventFlow.Configuration.Registrations.AutofacStartable' is not assignable to service 'Autofac.IStartable
during EventFlow setup
v0.16.1120
- Breaking: Removed
HasRegistrationFor<>
andGetRegisteredServices()
fromIServiceRegistration
and added them toIResolver
instead. The
methods required that all service registrations went through EventFlow,
which in most cases they will not - Obsolete: Marked
IServiceRegistration.RegisterIfNotRegistered(...)
, use
thekeepDefault = true
on the otherRegister(...)
methods instead - New: Major changes have been done to how EventFlow handles service
registration and bootstrapping in order for developers to skip calling
CreateResolver()
(orCreateContainer()
if using theEventFlow.Autofac
package) completely. EventFlow will register its bootstrap services in the
IoC container and configure itself whenever the container is created - New: Introduced
IBootstrap
interface that you can register. It has a
singleBootAsync(...)
method that will be called as soon as the IoC
container is ready (similar to that ofIStartable
of Autofac) - Fixed: Correct order of service registration decorators. They are now
applied in the same order they are applied, e.g., the last registered
service decorator will be the "outer" service - Fixed: Added missing
ICommand<,>
interface to abstractCommand<,>
class in
EventFlow.Commands
.
v0.15.1057
- Fixed: Added
UseHangfireJobScheduler()
and markedUseHandfireJobScheduler()
obsolete, fixing method spelling mistake
v0.14.1051
- Breaking: All
EventFlowOptions
extensions are nowIEventFlowOptions
instead andEventFlowOptions
implements this interface. If you have made
your own extensions, you will need to use the newly created interface
instead. Changed in order to make testing of extensions and classes
dependent on the EventFlow options easier to test - New: You can now bundle your configuration of EventFlow into modules that
implementIModule
and register these by calling
EventFlowOptions.RegisterModule(...)
- New: EventFlow now supports scheduled job execution via e.g. Hangfire. You
can create your own scheduler or install the newEventFlow.Hangfire
NuGet
package. Read the jobs documentation for more details - New: Created the OWIN
CommandPublishMiddleware
middleware that can
handle publishing of commands by posting a JSON serialized command to
e.g./commands/ping/1
in whichping
is the command name and1
its
version. Remember to add authentication - New: Created a new interface
ICommand<TAggregate,TIdentity,TSourceIdentity>
to allow developers to control the type ofICommand.SourceId
. Using the
ICommand<TAggregate,TIdentity>
(or Command<TAggregate,TIdentity>)
will still yield the same result as before, i.e.,ICommand.SourceId
being
of typeISourceId
- New: The
AddDefaults(...)
now also adds the command type definition to the
newICommandDefinitonService
v0.13.962
- Breaking:
EventFlowOptions.AddDefaults(...)
now also adds query handlers - New: Added an optional
Predicate<Type>
to the following option extension
methods that scan anAssembly
:AddAggregateRoots(...)
,
AddCommandHandlers(...)
,AddDefaults(...)
,AddEventUpgraders(...)
,
AddEvents(...)
,AddMetadataProviders(...)
,AddQueryHandlers(...)
and
AddSubscribers(...)
- Fixed:
EventFlowOptions.AddAggregateRoots(...)
now prevents abstract
classes from being registered when passingIEnumerable<Type>
- Fixed: Events published to RabbitMQ are now in the right order for chains
of subscribers, ifevent A -> subscriber -> command -> aggregate -> event B
,
then the order of published events to RabbitMQ wasevent B
and then
event A
v0.12.891
- Breaking: Aggregate root no longer have
Aggregate
removed from their
when name, i.e., the metadata property with keyaggregate_name
(or
MetadataKeys.AggregateName
). If you are dependent on the previous naming,
use the newAggregateName
attribute and apply it to your aggregates - Breaking: Moved
Identity<>
andIIdentity
from theEventFlow.Aggregates
namespace toEventFlow.Core
as the identities are not specific for aggregates - Breaking:
ICommand.Id
is renamed toICommand.AggregateId
to make "room"
for the newICommand.SourceId
property. If commands are serialized, then
it might be important verify that the serialization still works. EventFlow
does not serialize commands, so no mitigation is provided. If the
Command<,>
is used, make sure to use the correct protected constructor - Breaking:
IEventStore.StoreAsync(...)
now requires an additional
ISourceId
argument. To create a random one, useSourceId.New
, but it
should be e.g. the command ID that resulted in the events. Note, this method
isn't typically used by developers - New: Added
ICommand.SourceId
, which contains the ID of the source. The
default (if your commands inherit fromCommand<,>
) will be a new
CommandId
each time the aCommand<,>
instance is created. You can pass
specific value, merely use the newly added constructor taking the ID.
Alternatively you commands could inherit from the new
DistinctCommand
, enabling commands with the same state to have the
sameSourceId
- New: Duplicate commands can be detected using the new
ISourceId
. Read the
EventFlow article regarding commands for more details - New: Aggregate names can now be configured using the attribute
AggregateName
. The name can be accessed using the newIAggregateRoot.Name
property - New: Added
Identity<>.NewDeterministic(Guid, string)
enabling creation of
deterministic GUIDs - New: Added new metadata key
source_id
(MetadataKeys.SourceId
) containing
the source ID, typically the ID of the command from which the event
originated - New: Added new metadata key
event_id
(MetadataKeys.EventId
) containing a
deterministic ID for the event. Events with the same aggregate sequence
number and from aggregates with the same identity, will have the same event
identity - Fixed:
Identity<>.With(string)
now throws anArgumentException
instead of
aTargetInvocationException
when passed an invalid identity - Fixed: Aggregate roots now build the cache of
Apply
methods once, instead
of when the method is requested the first time
v0.11.751
- Breaking:
EventFlowOptions.AddDefaults(...)
now also adds event
definitions - New: RabbitMQ is now supported through the new
NuGet package calledEventFlow.RabbitMQ
which enables domain events to be
published to the bus - New: If you want to subscribe to all domain events, you can implement
and register a service that implementsISubscribeSynchronousToAll
. Services
that implement this will automatically be added using the
AddSubscribers(...)
orAddDefaults(...)
extension toEventFlowOptions
- New: Use
EventFlowOptions.UseAutofacAggregateRootFactory(...)
to use an
Autofac aggregate root factory, enabling you to use services in your
aggregate root constructor - New: Use
EventFlowOptions.UseResolverAggregateRootFactory()
to use the
resolver to create aggregate roots. Same as
UseAutofacAggregateRootFactory(...)
but for when using the internal IoC
container - New: Use
EventFlowOptions.AddAggregateRoots(...)
to register aggregate root
types - New: Use
IServiceRegistration.RegisterType(...)
to register services by
type