Service Logic
Service Logic executes on create, read, update or delete of an entity. Service Logic classes are automatically discovered and executed by the framework.
Logic Stage
Service Logic can execute at the listed stages below.
- PreValidation: Before security validation and before the save to the
database. This occurs before validation attributes such as
UIRequired,UIReadOnly,UICreateOnly, andUICharacterLimitare checked. If setting a required field in Service Logic, use PreValidation. - PreOperation: After security validation and before the save to the database
- PostOperation: After the save to the database
Create Service Logic
To create Service Logic, create a new file in the project in the Services folder.
Project / Services / MyEntityService.cs
The ServiceLogic attribute takes the following parameters.
- TableName: The name of the entity the service logic will execute on. '*' for all entities.
- DataOperations: Flags that determine what data operations this should execute on, create, read, update, and delete.
- LogicStages: Flags that determine which stages the service logic should exeucte on, PreOperation, or PostOperation.
- Order: Service Logic classes executing on the same table, data operation, and logic stage, will execute following the order.
ServiceContext
ServiceContext has a number of properties that can be used during execution.
Project / Services / MyEntityService.cs
Modify Records
Use the Create, Update, and Delete methods of the ServiceContext to modify records. While it is possible to modify records directly using the Entity Framework DbContext, using the ServiceContext ensures that the service logic is executed.
Project / Logic / MyEntityService.cs
Dependency Injection
Service Logic classes support constructor-based dependency injection. The framework uses ActivatorUtilities.CreateInstance() to instantiate service logic classes, allowing automatic injection of registered services:
Project / Services / WidgetService.cs
Performance
For optimal performance, prioritize using PreOperation logic whenever possible. This allows the database save to be delayed until all records are processed, or until an entity with PostOperation logic is triggered.
Best Practices
ValueChanged
- Always use
context.ValueChanged("FieldName")to check if a field has changed instead of comparing values directly between thePreEntityandEntity. This will always return true on create operations.
Use context.Create/Update/Delete
Always use context.Create/Update/Delete() - Direct db.Add() bypasses service logic and validations.
Code Organization
- Isolate logic into separate methods and use defensive coding to ensure it executes only when expected.
Project / Services / UserService.cs
Error Handling
Do not throw exceptions from service logic. Instead return a failed ServiceResult with an appropriate error message.