Benevia.Core.Events
Maintainers
- @GlennEsh
- @AkhmedovSanjar - Has a deep understanding of the event system and can provide insights into its design and functionality.
Introduction
Modules
Architecture
Logic containers
Logic containers contain the business logic for an entity or data type. Each entity or data type has a corresponding logic container class that holds its business logic methods. This is a singleton class that is instantiated once per application lifetime.
- The logic container class is generated automatically based on the entity in the model. If the entity defined in the model is
Contact, the logic container class will beContact.Logic. - When the app starts up, logic is registered. This is done in a business logic class that is decorated with the [Logic] attribute and it can have one or more logic container parameters. Event methods must be decorated with the [RegisterLogic] attribute. Example:
[Logic]
public class ContactBL(Contact.Logic contact)
{
[RegisterLogic]
public void ContactBL()
{
// This method runs on startup. Add logic to the contact logic container here.
}
}
Setup
<commands / code samples>
State
The State module tracks changes to entities and their properties during business logic execution.
Entity State
EntityState manages the overall state of entities and keeps track of all their properties.
customer._State.FullName.IsDirty; //If true, the FullName property will fire compute events when read.
customer._State.OriginalValue //Get original value of the entity before any changes.
Property State
PropertyState manages individual property changes with:
- Original vs. new values
- Validation status
- Change tracking
This lets the system track what changed, validate data before saving, and manage property updates during business logic execution.
Base Event
BaseEvent provides common functionality for all events including event descriptions and tracing support for monitoring and debugging.
LogicBuilders
Logic builders provide a clean, readable way to define business logic using method chaining (Fluent).
Events Handler Pattern
Most event handlers follow a consistent pattern that accepts both the entity and the event arguments:
public delegate void SomeEventHandler<TEntity>(TEntity entity, SomeEventArgs args) where TEntity : IEntity, IEventEntity;
This allows subscribers to choose between a simple signature or a more detailed one:
.Do(entity => ...).Do((entity, args) => ...)
EventArgs Base Class
All event argument classes inherit from a common EventArgs base class, which provides utility methods to interact with the environment:
- Context: Access the current
EventContext. - GetService
() : Resolve services from the scoped service provider. - GetEntities
() : Access other entities via queryable. - GetEntity
(id/key) : Retrieve specific entities.
Example:
.Do((entity, args) => {
var service = args.GetService<IMyService>();
var otherEntities = args.GetEntities<OtherEntity>();
});