-
Notifications
You must be signed in to change notification settings - Fork 0
Events
Event types should extend/implement Event interface:
interface BuyEvent : Event {
val product: Product
val amount: Int
}This is very recommended to use interfaces to create events instead of concrete classes because of EventSys features like Properties and Extensions.
EventSys generates event implementations dynamically at runtime (compile-time generation is planned), to do that there are some alternatives, like using Factory interface or Handwritten code.
The factory interface is the easiest way to create event instances, example:
interface MyFactory {
fun createBuyEvent(@Name("product") product: Product, @Name("amount") amount: Int): BuyEvent
}Now you need to create the instance of factory, to do that, call EventGenerator.createFactory of EventManager.eventGenerator:
val factory = eventManager.eventGenerator.createFactory<MyFactory>()And finally invoke the factory function:
val buyEvent = factory.createBuyEvent(...);Note: In kotlin classes, you don't need to use @Name because EventSys can use Kotlin-reflect to get name of parameters, but this annotation speed-up the process a bit. Letting EventSys get names through kotlin reflect affects the performance, and it only does if @Name is not present.
Also you could create event class using EventGenerator, but this process is a bit tricky because that the Factory generator requests the event generation and invokes the constructor of the class directly, without reflection or method handle (unless factory function is annotated with @LazyGeneration). To do that without the Factory interface we need to use reflection to determine the order of arguments and invoke constructor. Happily, EventSys has an utility function to do the hard work for you.
The first step is to request event class generation:
val manager = ...
val eventClass = manager.eventGenerator.createEventClass<BuyEvent>()Now you should invoke the create function and pass the eventClass with a map of argument name to argument value:
val event = create(eventClass, mapOf(
"product" to Product("USB Adapter", 10.0),
"amount" to 5
))There is another way to implement events, using the concrete implementation (or handwritten implementation). But you should register the event implementation using the event generator:
fun staticEventsWiki() {
val manager = DefaultEventManager()
manager.eventGenerator.registerEventImplementation<BuyEvent>(
EventClassSpecification(TypeInfo.of(BuyEvent::class.java), emptyList(), emptyList()),
BuyEventImpl::class.java
)
}
data class BuyEventImpl(override val product: Product, override val amount: Int) : BuyEvent {
private val properties = Collections.unmodifiableMap(mapOf(
"product" to GetterProperty.Impl(Product::class.java, Supplier {this.product}),
"amount" to IntGetterProperty.Impl(IntSupplier {this.amount})
))
override fun getProperties(): Map<String, Property<*>> =
this.properties
}If you're wondering why there is a getProperties function, see Event Properties.
This is (currently) the right way to do that, but this does not means that every BuyEvent instance will be an instance of BuyEventImpl, EventSys will generate implementations dynamically in cases where event instance is requested with extensions and/or additionalProperties. But you could register concrete implementation with extensions and/or additional properties, and EventSys will use that implementation, but there is no way to register one concrete class that matches all EventSpecifications. To understand why this is not possible, you should read both Event Properties and Event Extensions.
You can still use Event Factories to create instances of concrete implemented events, but make sure to register them before creating the factory, if you create factory before registration, the factory will use generated classes rather than registered (because the factory request event generation to use concrete generated classes, unless you annotated factory function with @LazyGeneration).