When a domain event is emitted, the readmodel may need to update itself using not only the data in the domain event itself, but also some additional data coming from an external service.
To use a specific example, some of my domain events contain a UserId pointing to the user that caused the event to happen. In that case I want to also persist the user email and full name in the readmodel; thus while updating the readmodel I need to query some UserDataProvider.
Currently the IReadModelContext.Resolver can be used to resolve such services, but this smells of service locator anti-pattern. It is also theoretically possible to build your own ReadModelStore that would support injecting dependencies into readmodels via constructor, but this both requires plenty of work, and constructor injection into entities doesn't seem like a good idea to me, especially since it's basically prohibited in most popular ORMs, including the ones supported by EventFlow (Entity Framework, Dapper etc.).
The solution that comes to my mind would be to introduce a new interface, IAmReadModelFor<TAggregate, TIdentity, TEvent, TDependency>:
public interface IAmReadModelFor<TAggregate, TIdentity, TEvent, TDependency>
{
Task ApplyAsync(
IReadModelContext context,
IDomainEvent<TAggregate, TIdentity, TEvent> domainEvent,
TDependency dependency,
CancellationToken cancellationToken);
}
In this solution, ReadModelDomainEventApplier could use IResolver to resolve the TDependency and inject it into the readmodel, which would thus conform to recommended dependency injection rules.
What do you think of this idea? I can try to implement it, if my time and abilities permit it.
related to #373
When a domain event is emitted, the readmodel may need to update itself using not only the data in the domain event itself, but also some additional data coming from an external service.
To use a specific example, some of my domain events contain a
UserIdpointing to the user that caused the event to happen. In that case I want to also persist the user email and full name in the readmodel; thus while updating the readmodel I need to query someUserDataProvider.Currently the
IReadModelContext.Resolvercan be used to resolve such services, but this smells of service locator anti-pattern. It is also theoretically possible to build your ownReadModelStorethat would support injecting dependencies into readmodels via constructor, but this both requires plenty of work, and constructor injection into entities doesn't seem like a good idea to me, especially since it's basically prohibited in most popular ORMs, including the ones supported by EventFlow (Entity Framework, Dapper etc.).The solution that comes to my mind would be to introduce a new interface,
IAmReadModelFor<TAggregate, TIdentity, TEvent, TDependency>:In this solution,
ReadModelDomainEventAppliercould useIResolverto resolve theTDependencyand inject it into the readmodel, which would thus conform to recommended dependency injection rules.What do you think of this idea? I can try to implement it, if my time and abilities permit it.
related to #373