added domain events, fix IQueryalbeProvider abstraction, added support for sagas and RabbitMQ
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Svrnty.CQRS.DynamicQuery;
|
||||
|
||||
/// <summary>
|
||||
/// Builder for configuring DynamicQuery services.
|
||||
/// </summary>
|
||||
public class DynamicQueryServicesBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// The service collection being configured.
|
||||
/// </summary>
|
||||
public IServiceCollection Services { get; }
|
||||
|
||||
internal DynamicQueryServicesBuilder(IServiceCollection services)
|
||||
{
|
||||
Services = services;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using PoweredSoft.Data.Core;
|
||||
|
||||
namespace Svrnty.CQRS.DynamicQuery;
|
||||
|
||||
/// <summary>
|
||||
/// In-memory implementation of IAsyncQueryableService.
|
||||
/// For EF Core projects, use AddDynamicQueryServices().UseEntityFramework() instead.
|
||||
/// </summary>
|
||||
public class InMemoryAsyncQueryableService : IAsyncQueryableService
|
||||
{
|
||||
public IEnumerable<IAsyncQueryableHandlerService> Handlers { get; } = Array.Empty<IAsyncQueryableHandlerService>();
|
||||
|
||||
public Task<List<TSource>> ToListAsync<TSource>(IQueryable<TSource> queryable, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(queryable.ToList());
|
||||
}
|
||||
|
||||
public Task<TSource?> FirstOrDefaultAsync<TSource>(IQueryable<TSource> queryable, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(queryable.FirstOrDefault());
|
||||
}
|
||||
|
||||
public Task<TSource?> FirstOrDefaultAsync<TSource>(IQueryable<TSource> queryable, Expression<Func<TSource, bool>> predicate, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(queryable.FirstOrDefault(predicate));
|
||||
}
|
||||
|
||||
public Task<TSource?> LastOrDefaultAsync<TSource>(IQueryable<TSource> queryable, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(queryable.LastOrDefault());
|
||||
}
|
||||
|
||||
public Task<TSource?> LastOrDefaultAsync<TSource>(IQueryable<TSource> queryable, Expression<Func<TSource, bool>> predicate, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(queryable.LastOrDefault(predicate));
|
||||
}
|
||||
|
||||
public Task<bool> AnyAsync<TSource>(IQueryable<TSource> queryable, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(queryable.Any());
|
||||
}
|
||||
|
||||
public Task<bool> AnyAsync<TSource>(IQueryable<TSource> queryable, Expression<Func<TSource, bool>> predicate, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(queryable.Any(predicate));
|
||||
}
|
||||
|
||||
public Task<bool> AllAsync<TSource>(IQueryable<TSource> queryable, Expression<Func<TSource, bool>> predicate, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(queryable.All(predicate));
|
||||
}
|
||||
|
||||
public Task<int> CountAsync<TSource>(IQueryable<TSource> queryable, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(queryable.Count());
|
||||
}
|
||||
|
||||
public Task<long> LongCountAsync<TSource>(IQueryable<TSource> queryable, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(queryable.LongCount());
|
||||
}
|
||||
|
||||
public Task<TSource?> SingleOrDefaultAsync<TSource>(IQueryable<TSource> queryable, Expression<Func<TSource, bool>> predicate, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(queryable.SingleOrDefault(predicate));
|
||||
}
|
||||
|
||||
public IAsyncQueryableHandlerService? GetAsyncQueryableHandler<TSource>(IQueryable<TSource> queryable)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,31 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using PoweredSoft.Data.Core;
|
||||
using PoweredSoft.DynamicQuery;
|
||||
using PoweredSoft.DynamicQuery.Core;
|
||||
using Svrnty.CQRS.Abstractions;
|
||||
using Svrnty.CQRS.Abstractions.Discovery;
|
||||
using Svrnty.CQRS.DynamicQuery.Abstractions;
|
||||
using Svrnty.CQRS.DynamicQuery.Discover;
|
||||
using PoweredSoft.DynamicQuery.Core;
|
||||
|
||||
namespace Svrnty.CQRS.DynamicQuery;
|
||||
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers core DynamicQuery services with in-memory async queryable.
|
||||
/// For EF Core projects, chain with .UseEntityFramework().
|
||||
/// </summary>
|
||||
/// <param name="services">The service collection.</param>
|
||||
/// <returns>A builder for further configuration.</returns>
|
||||
public static DynamicQueryServicesBuilder AddDynamicQueryServices(this IServiceCollection services)
|
||||
{
|
||||
services.TryAddTransient<IAsyncQueryableService, InMemoryAsyncQueryableService>();
|
||||
services.TryAddTransient<IQueryHandlerAsync, QueryHandlerAsync>();
|
||||
return new DynamicQueryServicesBuilder(services);
|
||||
}
|
||||
|
||||
public static IServiceCollection AddDynamicQuery<TSourceAndDestination>(this IServiceCollection services, string name = null)
|
||||
where TSourceAndDestination : class
|
||||
=> AddDynamicQuery<TSourceAndDestination, TSourceAndDestination>(services, name: name);
|
||||
@@ -55,6 +70,22 @@ public static class ServiceCollectionExtensions
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a custom queryable provider override for the specified source type.
|
||||
/// Use this for DTOs that require custom projection from entities.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The DTO/Item type returned by the queryable.</typeparam>
|
||||
/// <typeparam name="TProvider">The provider implementation type.</typeparam>
|
||||
/// <param name="services">The service collection.</param>
|
||||
/// <returns>The service collection for chaining.</returns>
|
||||
public static IServiceCollection AddQueryableProviderOverride<TSource, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TProvider>(this IServiceCollection services)
|
||||
where TSource : class
|
||||
where TProvider : class, IQueryableProviderOverride<TSource>
|
||||
{
|
||||
services.AddTransient<IQueryableProvider<TSource>, TProvider>();
|
||||
return services;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddDynamicQueryWithParams<TSourceAndDestination, TParams>(this IServiceCollection services, string name = null)
|
||||
where TSourceAndDestination : class
|
||||
where TParams : class
|
||||
|
||||
Reference in New Issue
Block a user