JasperFx / marten

.NET Transactional Document DB and Event Store on PostgreSQL
https://martendb.io
MIT License
2.79k stars 441 forks source link

Formal Specification pattern implementation in Marten for usages where compiled queries aren't usable #3318

Closed jeremydmiller closed 1 month ago

jeremydmiller commented 1 month ago

See this for a little more background: https://medium.com/@arjunarora171997/specification-design-pattern-8ce9f7897a83#:~:text=The%20specification%20design%20pattern%20is%20basically%20you%20first%20preparing%20a,from%20other%20tables)%2C%20etc.

I've always said that the compiled query feature is Marten's version of the "Specification pattern", but I'm working with a client where I think there would be a lot of value in having an alternative "Specification" usage for weirder things that can't work inside of a compiled query.

The goal in a way is to have reusable query specifications while also nuking the typical stupid Clean Architecture style repository abstractions that take away all the power.

Bonus: do this in such a way that you can still use at least some of these things with batched queries as well.

jeremydmiller commented 1 month ago

// This will be in https://github.com/JasperFx/marten/issues/3318, but a bit more integrated
public interface IQueryPlan<T>
{
    Task<T> Fetch(IQuerySession session, CancellationToken cancellationToken);
}

// it'll be fancier to try to enable batch querying
public class QuerySession
{
    public Task<T> QueryAsync<T>(this IDocumentSession session, IQueryPlan<T> plan, CancellationToken cancellationToken)
    {
        return plan.Fetch(session, cancellationToken);
    }
}