-
Notifications
You must be signed in to change notification settings - Fork 12
Creating events
Events are messages that are held in an instance of an entity class (i.e. a class that EF Core maps to a database) and convey that a certain event has happened and needs processing by a event handler. Events often sends over data in the event which is given to the appropriate event handler. A event must inherit the IEntityEvent interface (which is empty, and use a placeholder).
public class TaxRateChangedEvent : IEntityEvent
{
public TaxRateChangedEvent(decimal newTaxRat)
{
NewTaxRate = newTaxRate;
}
public decimal NewTaxRate { get; }
}NOTE: You can add the [RemoveDuplicateEvents] attribute to an event class. This will remove duplicate events of the same class type and has the same entity class instance (as determined by the ReferenceEquals method). This can be useful if you might get multiple events - especially on During events as you don't want multiple calls to an external system.
There are three types of events that EFCore.GenericEventRunner supports. They are:
Before events are run before SaveChanges/SaveChangesAsync is called. This type of event is great for triggering some business logic (held in your event hander) to deal with a side effect of the entity class/property being changed.
See this example which shows how a seemly simple changes to a location had big side effect (changing the sales tax code of a job). This is a great example of using Before events to handle the recalc of the sales tax separately from the mundane change of the location's State/County.
Executing a Before event can create another Before event (this are known as saga). For this reason the library will loop around until there are no new Before events to run. NOTE: See this document about how it detects a circular Before event problem.
These are run within a transaction after
SaveChanges/SaveChangesAsync has been called, but before the transaction's Commit has been called. This type of event is normally used for talking to a separate part of your application, or say an external service. You use this when you want to ensure the update of the local database not goes ahead if the other external part/service was successful. Think of this glueing the two parts: the local database update and the external action together - both only work if both are successful.
See this example of this type of event to make sure two databases are in step with each other, i.e. only if second database is successfully updated will the first database's updates are committed.
NOTE: EFCore.GenericEventRunner didn't support During events when I wrote that article, but EFCore.GenericEventRunner 2.1 and above supports During events.
These are run after the SaveChanges/SaveChangesAsyncmethod has finished successfully. This type of event is useful to say send an email once you are sure that the Order has been checked and written to the database. Also good for clearing a cached version of the entity that has been successfully updated.