Services
Business logic, @ServiceImplementation, constructor injection, and the service lifecycle.
Defining a Service
A service has two parts:
- Interface — defined in the
core-*module. - Implementation — annotated with
@ServiceImplementation. KSP generates the DI wiring.
Interface (in core-* module)
kotlin
Implementation
kotlin
Constructor Injection
Dependencies are injected via the constructor. KSP reads the constructor parameters and generates the provider wiring. You can inject:
- Repositories —
@Repository-annotated interfaces - Other services — via their interface
- Infrastructure —
CacheManager,PubSubService,BoscaApplication, etc. ObjectProvider<T>— for lazy/deferred resolution
Service Responsibilities
A service typically handles:
- Cache-through reads — look up in cache first, fall back to repository on miss.
- Writes with cache invalidation — perform the repository write, then invalidate all affected caches.
- Event dispatch — dispatch domain events after writes for background jobs and subscribers.
- Business logic — validation, transformation, orchestration across repositories.
Services should not handle authentication or authorization — that belongs in the controller layer via
PermissionEvaluator and GroupEvaluator. Event Dispatch
Services dispatch domain events after writes using KSP-generated dispatch() extensions:
kotlin
See Messaging & Events for full details.