Releases: eventflow/EventFlow
v0.17.1134
- Fixed: Using NuGet package
EventFlow.Autofaccauses an exception with the
messageThe type 'EventFlow.Configuration.Registrations.AutofacStartable' is not assignable to service 'Autofac.IStartableduring EventFlow setup
v0.16.1120
- Breaking: Removed
HasRegistrationFor<>andGetRegisteredServices()
fromIServiceRegistrationand added them toIResolverinstead. The
methods required that all service registrations went through EventFlow,
which in most cases they will not - Obsolete: Marked
IServiceRegistration.RegisterIfNotRegistered(...), use
thekeepDefault = trueon 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
IBootstrapinterface that you can register. It has a
singleBootAsync(...)method that will be called as soon as the IoC
container is ready (similar to that ofIStartableof 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
EventFlowOptionsextensions are nowIEventFlowOptions
instead andEventFlowOptionsimplements 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
implementIModuleand 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.HangfireNuGet
package. Read the jobs documentation for more details - New: Created the OWIN
CommandPublishMiddlewaremiddleware that can
handle publishing of commands by posting a JSON serialized command to
e.g./commands/ping/1in whichpingis the command name and1its
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.SourceIdbeing
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 Band then
event A
v0.12.891
- Breaking: Aggregate root no longer have
Aggregateremoved 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 newAggregateNameattribute and apply it to your aggregates - Breaking: Moved
Identity<>andIIdentityfrom theEventFlow.Aggregates
namespace toEventFlow.Coreas the identities are not specific for aggregates - Breaking:
ICommand.Idis renamed toICommand.AggregateIdto make "room"
for the newICommand.SourceIdproperty. 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
ISourceIdargument. 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
CommandIdeach 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 anArgumentExceptioninstead of
aTargetInvocationExceptionwhen passed an invalid identity - Fixed: Aggregate roots now build the cache of
Applymethods 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.RabbitMQwhich 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
v0.10.642
- Breaking: Updated NuGet reference
Newtonsoft.Jsonto v7.0.1
(up from v6.0.8) - Breaking: Remove the empty constructor from
SingleValueObject<> - New: Added
SingleValueObjectConverterto 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 beprivateandprotected - 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
Dapperto v1.42 (up from v1.38)
v0.9.580
- Braking:
IEventStore.LoadAllEventsAsyncandIEventStore.LoadAllEvents
now take aGlobalPositionas an argument instead of alongfor the
starting position. TheGlobalPositionis basically a wrapper around a
string that hides the inner workings of each event store. - New: NuGet package
EventFlow.EventStores.EventStorethat 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
LastGlobalSequenceNumbercolumn during update, or set it to
defaultNULL IDomainEvent.GlobalSequenceNumberremovedIEventStore.LoadEventsAsyncandIEventStore.LoadEventstaking
aGlobalSequenceNumberRangeremoved
- 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.BatchIdto metadata and created
MetadataKeys.BatchIdto help access it -
New:
IEventStore.DeleteAggregateAsyncto 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:
IReadModelPopulatoris 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:
IEventStorenow hasLoadAllEventsAsyncandLoadAllEventsthat
enables you to load all events in the event store a few at a time. -
New:
IMetadata.TimestampEpochcontains the Unix timestamp version
ofIMetadata.Timestamp. Also, an additional metadata key
timestamp_epochis added to events containing the same data. Note,
theTimestampEpochonIMetadatahandles cases in which the
timestamp_epochis 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 anIEventUpgraderremoved events from the event stream -
Fixed:
InMemoryReadModelStore<,>is now thread safe