Using ServiceStack Architecture to Route Events instead of using Reflection?

I am currently working on a ServiceStack plugin for EventStore which can persist and rehydrate aggregates as well as subscribe to named event streams.

At the moment, the plugin handles an event arriving on a watched stream by inspecting the event type and dispatching it to a method that implements IHandle. This works well enough although like all implementations of the Observer Pattern the order in which subscribers are notified is not specified.

Is there a way that, instead of dispatching an event in this way - i.e. using Reflection to dispatch a ProductCreated event to a method that implements IHandle - we could route the event to a service method like Any(OrderCreated @event)? Is the custom ServceRunner designed for this purpose?

1 Like

You can call the ServiceController to execute Services by passing in a Request DTO, e.g:

HostContext.ServiceController.Execute(new OrderCreated { ... });

If the EventStore message is a POCO with matching properties you also want to copy to the Request DTO, you can use the built-in Auto Mapping, e.g:

HostContext.ServiceController.Execute(eventStoreMsg.ConvertTo<OrderCreated>());
2 Likes

Thanks, Demis. That could help us lose a fair bit of boilerplate!

So, we are taking the CLR type name of the event from the event’s own header and then resolving the type from a dictionary created via assembly scanning.

Now, instead of scanning for methods that implement IHandle I guess we could scan for the parameter types of methods in all classes that inherit from Service. Or does ServiceStack already have a list of these types?

You can get all metadata about your Services from HostContext.Metadata, the /types/metadata route shows some of the metadata available, e.g: http://test.servicestack.net/types/metadata.json

1 Like

I’ve used the Execute(DTO) pattern that @mythz mentions in combination with cron schedules (works well), by injecting the DTO to be executed into a Job pattern.

2 Likes

I got it working.

I’m pleased to say that I was able to jettison about 40 lines of code that was doing assembly scanning and dispatching. Always a Good Thing. :blush:

A question about HostContext.ServiceController.ExecuteAsync(...)

The signature is public Task<object> ExecuteAsync(object requestDto, IRequest req)

With the synchronous method I have just been passing in my event type/POCO. However, what would I need to pass in (that implements IRequest) as the second parameter to the ExecuteAsync method?

You can just pass in ‘new BasicRequest()’ which is also what gets passed when you call ‘Execute()’ with only the Request DTO.