Skip to content

Injecting dependencies into ReadModels #846

Description

@Yaevh

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions