initial commit for .net 8 migration
This commit is contained in:
		
							parent
							
								
									9015dc2d5f
								
							
						
					
					
						commit
						88c86513e9
					
				@ -1,54 +0,0 @@
 | 
			
		||||
using PoweredSoft.Data.Core;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Linq.Expressions;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Demo.AsyncProvider
 | 
			
		||||
{
 | 
			
		||||
    public class InMemoryQueryableHandler : IAsyncQueryableHandlerService
 | 
			
		||||
    {
 | 
			
		||||
        public Task<bool> AnyAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            return Task.FromResult(queryable.Any(predicate));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Task<bool> AnyAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            return Task.FromResult(queryable.Any());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool CanHandle<T>(IQueryable<T> queryable)
 | 
			
		||||
        {
 | 
			
		||||
            var result = queryable is EnumerableQuery<T>;
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Task<int> CountAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            return Task.FromResult(queryable.Count());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            return Task.FromResult(queryable.FirstOrDefault());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            return Task.FromResult(queryable.FirstOrDefault(predicate));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Task<long> LongCountAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            return Task.FromResult(queryable.LongCount());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Task<List<T>> ToListAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            return Task.FromResult(queryable.ToList());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,12 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
 | 
			
		||||
namespace Demo.Commands
 | 
			
		||||
{
 | 
			
		||||
    public class CreatePersonCommand
 | 
			
		||||
    {
 | 
			
		||||
        public string FirstName { get; set; }
 | 
			
		||||
        public string LastName { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,14 +0,0 @@
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Demo.Commands
 | 
			
		||||
{
 | 
			
		||||
    public class CreatePersonCommandHandler : ICommandHandler<CreatePersonCommand>
 | 
			
		||||
    {
 | 
			
		||||
        public Task HandleAsync(CreatePersonCommand command, CancellationToken cancellationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            return Task.CompletedTask;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,13 +0,0 @@
 | 
			
		||||
using FluentValidation;
 | 
			
		||||
 | 
			
		||||
namespace Demo.Commands
 | 
			
		||||
{
 | 
			
		||||
    public class CreatePersonCommandValidator : AbstractValidator<CreatePersonCommand>
 | 
			
		||||
    {
 | 
			
		||||
        public CreatePersonCommandValidator()
 | 
			
		||||
        {
 | 
			
		||||
            RuleFor(t => t.FirstName).NotEmpty();
 | 
			
		||||
            RuleFor(t => t.LastName).NotEmpty();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,31 +0,0 @@
 | 
			
		||||
using FluentValidation;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Demo.Commands
 | 
			
		||||
{
 | 
			
		||||
    public class EchoCommand
 | 
			
		||||
    {
 | 
			
		||||
        public string Message { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class EchoCommandValidator : AbstractValidator<EchoCommand>
 | 
			
		||||
    {
 | 
			
		||||
        public EchoCommandValidator()
 | 
			
		||||
        {
 | 
			
		||||
            RuleFor(t => t.Message).NotEmpty();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class EchoCommandHandler : ICommandHandler<EchoCommand, string>
 | 
			
		||||
    {
 | 
			
		||||
        public Task<string> HandleAsync(EchoCommand command, CancellationToken cancellationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            return Task.FromResult(command.Message);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,30 +0,0 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk.Web">
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <TargetFramework>net5.0</TargetFramework>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="FluentValidation.AspNetCore" Version="10.3.0" />
 | 
			
		||||
    <PackageReference Include="HotChocolate.AspNetCore" Version="11.3.4" />
 | 
			
		||||
    <PackageReference Include="Microsoft.AspNetCore.OData" Version="8.0.1" />
 | 
			
		||||
    <PackageReference Include="PoweredSoft.Data" Version="3.0.0" />
 | 
			
		||||
    <PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="6.1.5" />
 | 
			
		||||
    <PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.1.5" />
 | 
			
		||||
    <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.1.5" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS.AspNetCore\PoweredSoft.CQRS.AspNetCore.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS.DynamicQuery.Abstractions\PoweredSoft.CQRS.DynamicQuery.Abstractions.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS.DynamicQuery.AspNetCore\PoweredSoft.CQRS.DynamicQuery.AspNetCore.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS.DynamicQuery\PoweredSoft.CQRS.DynamicQuery.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS.FluentValidation\PoweredSoft.CQRS.FluentValidation.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS.GraphQL.FluentValidation\PoweredSoft.CQRS.GraphQL.FluentValidation.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS.GraphQL.HotChocolate.DynamicQuery\PoweredSoft.CQRS.GraphQL.HotChocolate.DynamicQuery.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS.GraphQL.HotChocolate\PoweredSoft.CQRS.GraphQL.HotChocolate.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS\PoweredSoft.CQRS.csproj" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
@ -1,15 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace Demo.DynamicQueries
 | 
			
		||||
{
 | 
			
		||||
    public class Contact
 | 
			
		||||
    {
 | 
			
		||||
        public long Id { get; set; }
 | 
			
		||||
        public string DisplayName { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class SearchContactParams
 | 
			
		||||
    {
 | 
			
		||||
        public string SearchDisplayName { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,23 +0,0 @@
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Demo.DynamicQueries
 | 
			
		||||
{
 | 
			
		||||
    public class ContactQueryableProvider : IQueryableProvider<Contact>
 | 
			
		||||
    {
 | 
			
		||||
        public Task<IQueryable<Contact>> GetQueryableAsync(object query, CancellationToken cancelllationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            var source = new List<Contact>
 | 
			
		||||
            {
 | 
			
		||||
                new Contact { Id = 1, DisplayName = "David L"},
 | 
			
		||||
                new Contact { Id = 2, DisplayName = "John Doe"} 
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var ret = source.AsQueryable();
 | 
			
		||||
            return Task.FromResult(ret);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,18 +0,0 @@
 | 
			
		||||
using Demo.Queries;
 | 
			
		||||
using PoweredSoft.DynamicQuery.Core;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
 | 
			
		||||
namespace Demo.DynamicQueries
 | 
			
		||||
{
 | 
			
		||||
    public class PersonConvertInterceptor : IQueryConvertInterceptor<Person, PersonModel>
 | 
			
		||||
    {
 | 
			
		||||
        public PersonModel InterceptResultTo(Person entity)
 | 
			
		||||
        {
 | 
			
		||||
            return new PersonModel
 | 
			
		||||
            {
 | 
			
		||||
                Id = entity.Id,
 | 
			
		||||
                FullName = entity.FirstName + " " + entity.LastName
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,10 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace Demo.DynamicQueries
 | 
			
		||||
{ 
 | 
			
		||||
    public class PersonModel
 | 
			
		||||
    {
 | 
			
		||||
        public long Id { get; set; }
 | 
			
		||||
        public string FullName { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,54 +0,0 @@
 | 
			
		||||
using Demo.Queries;
 | 
			
		||||
using PoweredSoft.DynamicQuery;
 | 
			
		||||
using PoweredSoft.DynamicQuery.Core;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace Demo.DynamicQueries
 | 
			
		||||
{
 | 
			
		||||
    public class PersonOptimizationInterceptor : IFilterInterceptor, ISortInterceptor
 | 
			
		||||
    {
 | 
			
		||||
        public IFilter InterceptFilter(IFilter filter)
 | 
			
		||||
        {
 | 
			
		||||
            if (filter is ISimpleFilter simpleFilter)
 | 
			
		||||
            {
 | 
			
		||||
                if (simpleFilter.Path.Equals(nameof(PersonModel.FullName), System.StringComparison.InvariantCultureIgnoreCase))
 | 
			
		||||
                    return new CompositeFilter
 | 
			
		||||
                    {
 | 
			
		||||
                        Type = filter.Type,
 | 
			
		||||
                        And = filter.And,
 | 
			
		||||
                        Filters = new List<IFilter> {
 | 
			
		||||
                            new SimpleFilter
 | 
			
		||||
                            {
 | 
			
		||||
                                Not = simpleFilter.Not,
 | 
			
		||||
                                And = false,
 | 
			
		||||
                                Type = simpleFilter.Type,
 | 
			
		||||
                                Value = simpleFilter.Value,
 | 
			
		||||
                                Path = nameof(Person.FirstName)
 | 
			
		||||
                            },
 | 
			
		||||
                            new SimpleFilter
 | 
			
		||||
                            {
 | 
			
		||||
                                Not = simpleFilter.Not,
 | 
			
		||||
                                And = false,
 | 
			
		||||
                                Type = simpleFilter.Type,
 | 
			
		||||
                                Value = simpleFilter.Value,
 | 
			
		||||
                                Path = nameof(Person.LastName)
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    };
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return filter;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<ISort> InterceptSort(IEnumerable<ISort> sort)
 | 
			
		||||
        {
 | 
			
		||||
            foreach(var s in sort)
 | 
			
		||||
            {
 | 
			
		||||
                if (s.Path.Equals(nameof(PersonModel.FullName), System.StringComparison.InvariantCultureIgnoreCase))
 | 
			
		||||
                    yield return new Sort(nameof(Person.LastName), s.Ascending);
 | 
			
		||||
                else
 | 
			
		||||
                    yield return s;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,33 +0,0 @@
 | 
			
		||||
using Demo.Queries;
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Demo.DynamicQueries
 | 
			
		||||
{
 | 
			
		||||
    public class PersonQueryableProvider : IQueryableProvider<Person>
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IEnumerable<Person> _persons = new List<Person>()
 | 
			
		||||
        {
 | 
			
		||||
            new Person
 | 
			
		||||
            {
 | 
			
		||||
                Id = 1,
 | 
			
		||||
                FirstName = "David",
 | 
			
		||||
                LastName = "Lebee"
 | 
			
		||||
            },
 | 
			
		||||
            new Person
 | 
			
		||||
            {
 | 
			
		||||
                Id = 2,
 | 
			
		||||
                FirstName = "John",
 | 
			
		||||
                LastName = "Doe"
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        public Task<IQueryable<Person>> GetQueryableAsync(object query, CancellationToken cancelllationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            return Task.FromResult(_persons.AsQueryable());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,19 +0,0 @@
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Demo.DynamicQueries
 | 
			
		||||
{
 | 
			
		||||
    public class SearchContactParamsService : IAlterQueryableService<Contact, Contact, SearchContactParams>
 | 
			
		||||
    {
 | 
			
		||||
        public Task<IQueryable<Contact>> AlterQueryableAsync(IQueryable<Contact> query, IDynamicQueryParams<SearchContactParams> dynamicQuery, CancellationToken cancellationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            var safe = dynamicQuery.GetParams()?.SearchDisplayName;
 | 
			
		||||
            if (!string.IsNullOrEmpty(safe))
 | 
			
		||||
                return Task.FromResult(query.Where(t => t.DisplayName.Contains(safe)));
 | 
			
		||||
 | 
			
		||||
            return Task.FromResult(query);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,26 +0,0 @@
 | 
			
		||||
using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.Extensions.Configuration;
 | 
			
		||||
using Microsoft.Extensions.Hosting;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Demo
 | 
			
		||||
{
 | 
			
		||||
    public class Program
 | 
			
		||||
    {
 | 
			
		||||
        public static void Main(string[] args)
 | 
			
		||||
        {
 | 
			
		||||
            CreateHostBuilder(args).Build().Run();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IHostBuilder CreateHostBuilder(string[] args) =>
 | 
			
		||||
            Host.CreateDefaultBuilder(args)
 | 
			
		||||
                .ConfigureWebHostDefaults(webBuilder =>
 | 
			
		||||
                {
 | 
			
		||||
                    webBuilder.UseStartup<Startup>();
 | 
			
		||||
                });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,28 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "$schema": "http://json.schemastore.org/launchsettings.json",
 | 
			
		||||
  "iisSettings": {
 | 
			
		||||
    "windowsAuthentication": false,
 | 
			
		||||
    "anonymousAuthentication": true,
 | 
			
		||||
    "iisExpress": {
 | 
			
		||||
      "applicationUrl": "http://localhost:52483",
 | 
			
		||||
      "sslPort": 44343
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "profiles": {
 | 
			
		||||
    "IIS Express": {
 | 
			
		||||
      "commandName": "IISExpress",
 | 
			
		||||
      "launchBrowser": false,
 | 
			
		||||
      "environmentVariables": {
 | 
			
		||||
        "ASPNETCORE_ENVIRONMENT": "Development"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "Demo": {
 | 
			
		||||
      "commandName": "Project",
 | 
			
		||||
      "launchBrowser": false,
 | 
			
		||||
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
 | 
			
		||||
      "environmentVariables": {
 | 
			
		||||
        "ASPNETCORE_ENVIRONMENT": "Development"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -1,32 +0,0 @@
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions;
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Demo.Queries
 | 
			
		||||
{
 | 
			
		||||
    public class OnePersonQuery
 | 
			
		||||
    {
 | 
			
		||||
        public long PersonId { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class OnePersonQueryHandler : IQueryHandler<OnePersonQuery, Person>
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IQueryableProvider<Person> provider;
 | 
			
		||||
 | 
			
		||||
        public OnePersonQueryHandler(IQueryableProvider<Person> provider)
 | 
			
		||||
        {
 | 
			
		||||
            this.provider = provider;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<Person> HandleAsync(OnePersonQuery query, CancellationToken cancellationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            var _ = await provider.GetQueryableAsync(query, cancellationToken);
 | 
			
		||||
            var ret = _.First(t => t.Id == query.PersonId);
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,39 +0,0 @@
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions;
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Demo.Queries
 | 
			
		||||
{
 | 
			
		||||
    public class ListPersonQuery
 | 
			
		||||
    {
 | 
			
		||||
        public string Search { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class ListPersonQueryHandler : IQueryHandler<ListPersonQuery, List<Person>>
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IQueryableProvider<Person> provider;
 | 
			
		||||
 | 
			
		||||
        public ListPersonQueryHandler(IQueryableProvider<Person> provider)
 | 
			
		||||
        {
 | 
			
		||||
            this.provider = provider;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<List<Person>> HandleAsync(ListPersonQuery query, CancellationToken cancellationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            var _ = await provider.GetQueryableAsync(query, cancellationToken);
 | 
			
		||||
 | 
			
		||||
            if (query.Search != null)
 | 
			
		||||
                _ = _
 | 
			
		||||
                    .Where(t => t.FirstName.Contains(query.Search, StringComparison.InvariantCultureIgnoreCase) ||
 | 
			
		||||
                        t.LastName.Contains(query.Search, StringComparison.InvariantCultureIgnoreCase));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            var ret = _.ToList();
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,16 +0,0 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace Demo.Queries
 | 
			
		||||
{
 | 
			
		||||
    public class Person
 | 
			
		||||
    {
 | 
			
		||||
        public long Id { get; set; }
 | 
			
		||||
        public string FirstName { get; set; }
 | 
			
		||||
        public string LastName { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class PersonQuery
 | 
			
		||||
    {
 | 
			
		||||
        public string Search { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,29 +0,0 @@
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions;
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Demo.Queries
 | 
			
		||||
{
 | 
			
		||||
    public class PersonQueryHandler : IQueryHandler<PersonQuery, IQueryable<Person>>
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IQueryableProvider<Person> queryableProvider;
 | 
			
		||||
 | 
			
		||||
        public PersonQueryHandler(IQueryableProvider<Person> queryableProvider)
 | 
			
		||||
        {
 | 
			
		||||
            this.queryableProvider = queryableProvider;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<IQueryable<Person>> HandleAsync(PersonQuery query, CancellationToken cancellationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            var ret = await queryableProvider.GetQueryableAsync(query);
 | 
			
		||||
 | 
			
		||||
            if (query != null && !string.IsNullOrEmpty(query.Search))
 | 
			
		||||
                ret = ret.Where(t => t.FirstName.Contains(query.Search) || t.LastName.Contains(query.Search));
 | 
			
		||||
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,31 +0,0 @@
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions.Security;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Demo.Security
 | 
			
		||||
{
 | 
			
		||||
    public class CommandAndQueryAuthorizationService : IQueryAuthorizationService, ICommandAuthorizationService
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IHttpContextAccessor httpContextAccessor;
 | 
			
		||||
 | 
			
		||||
        public CommandAndQueryAuthorizationService(IHttpContextAccessor httpContextAccessor)
 | 
			
		||||
        {
 | 
			
		||||
            this.httpContextAccessor = httpContextAccessor;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Task<AuthorizationResult> IsAllowedAsync(Type queryOrCommandType, CancellationToken cancellationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            var authResult = httpContextAccessor.HttpContext.Request.Query["auth-result"].FirstOrDefault();
 | 
			
		||||
            if (authResult == "Unauthorized")
 | 
			
		||||
                return Task.FromResult(AuthorizationResult.Unauthorized);
 | 
			
		||||
            else if (authResult == "Forbidden")
 | 
			
		||||
                return Task.FromResult(AuthorizationResult.Forbidden);
 | 
			
		||||
 | 
			
		||||
            return Task.FromResult(AuthorizationResult.Allowed);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										145
									
								
								Demo/Startup.cs
									
									
									
									
									
								
							
							
						
						
									
										145
									
								
								Demo/Startup.cs
									
									
									
									
									
								
							@ -1,145 +0,0 @@
 | 
			
		||||
using Demo.AsyncProvider;
 | 
			
		||||
using Demo.Commands;
 | 
			
		||||
using Demo.DynamicQueries;
 | 
			
		||||
using Demo.Queries;
 | 
			
		||||
using FluentValidation;
 | 
			
		||||
using FluentValidation.AspNetCore;
 | 
			
		||||
using Microsoft.AspNetCore.Builder;
 | 
			
		||||
using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.Extensions.Configuration;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using Microsoft.Extensions.Hosting;
 | 
			
		||||
using PoweredSoft.CQRS;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions;
 | 
			
		||||
using PoweredSoft.CQRS.AspNetCore.Mvc;
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery;
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery.AspNetCore;
 | 
			
		||||
using PoweredSoft.CQRS.GraphQL.FluentValidation;
 | 
			
		||||
using PoweredSoft.CQRS.GraphQL.HotChocolate;
 | 
			
		||||
using PoweredSoft.Data;
 | 
			
		||||
using PoweredSoft.Data.Core;
 | 
			
		||||
using PoweredSoft.DynamicQuery;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using PoweredSoft.CQRS.GraphQL.HotChocolate.DynamicQuery;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions.Security;
 | 
			
		||||
using Demo.Security;
 | 
			
		||||
using PoweredSoft.CQRS.FluentValidation;
 | 
			
		||||
using Microsoft.AspNetCore.OData;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace Demo
 | 
			
		||||
{
 | 
			
		||||
    public class Startup
 | 
			
		||||
    {
 | 
			
		||||
        public Startup(IConfiguration configuration)
 | 
			
		||||
        {
 | 
			
		||||
            Configuration = configuration;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IConfiguration Configuration { get; }
 | 
			
		||||
 | 
			
		||||
        // This method gets called by the runtime. Use this method to add services to the container.
 | 
			
		||||
        public void ConfigureServices(IServiceCollection services)
 | 
			
		||||
        {
 | 
			
		||||
            AddQueries(services);
 | 
			
		||||
            AddDynamicQueries(services);
 | 
			
		||||
            AddCommands(services);
 | 
			
		||||
 | 
			
		||||
            services.AddHttpContextAccessor();
 | 
			
		||||
            services.AddTransient<IQueryAuthorizationService, CommandAndQueryAuthorizationService>();
 | 
			
		||||
            services.AddTransient<ICommandAuthorizationService, CommandAndQueryAuthorizationService>();
 | 
			
		||||
            services.AddTransient<IAsyncQueryableHandlerService, InMemoryQueryableHandler>();
 | 
			
		||||
            services.AddPoweredSoftDataServices();
 | 
			
		||||
            services.AddPoweredSoftDynamicQuery();
 | 
			
		||||
 | 
			
		||||
            services.AddPoweredSoftCQRS();
 | 
			
		||||
 | 
			
		||||
            services
 | 
			
		||||
                .AddControllers()
 | 
			
		||||
                .AddPoweredSoftQueries()
 | 
			
		||||
                .AddPoweredSoftCommands()
 | 
			
		||||
                .AddPoweredSoftDynamicQueries()
 | 
			
		||||
                .AddFluentValidation();
 | 
			
		||||
 | 
			
		||||
            services
 | 
			
		||||
                .AddGraphQLServer()
 | 
			
		||||
                .AddProjections()
 | 
			
		||||
                .AddQueryType(d => d.Name("Query"))
 | 
			
		||||
                .AddPoweredSoftQueries()
 | 
			
		||||
                .AddPoweredSoftDynamicQueries()
 | 
			
		||||
                .AddMutationType(d => d.Name("Mutation"))
 | 
			
		||||
                .AddPoweredSoftMutations();
 | 
			
		||||
 | 
			
		||||
            services.AddPoweredSoftGraphQLFluentValidation();
 | 
			
		||||
 | 
			
		||||
            services.AddSwaggerGen();
 | 
			
		||||
            services.AddCors();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void AddDynamicQueries(IServiceCollection services)
 | 
			
		||||
        {
 | 
			
		||||
            services.AddTransient<IQueryableProvider<Contact>, ContactQueryableProvider>();
 | 
			
		||||
            services.AddDynamicQuery<Contact>();
 | 
			
		||||
            services.AddDynamicQueryWithParams<Contact, SearchContactParams>(name: "SearchContacts")
 | 
			
		||||
                .AddAlterQueryableWithParams<Contact, SearchContactParams, SearchContactParamsService>();
 | 
			
		||||
 | 
			
		||||
            services
 | 
			
		||||
                .AddTransient<IQueryableProvider<Person>, PersonQueryableProvider>()
 | 
			
		||||
                .AddDynamicQuery<Person, PersonModel>(name: "People")
 | 
			
		||||
                .AddDynamicQueryInterceptors<Person, PersonModel, PersonConvertInterceptor, PersonOptimizationInterceptor>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void AddCommands(IServiceCollection services)
 | 
			
		||||
        {
 | 
			
		||||
            services.AddCommand<CreatePersonCommand, CreatePersonCommandHandler>();
 | 
			
		||||
            services.AddTransient<IValidator<CreatePersonCommand>, CreatePersonCommandValidator>();
 | 
			
		||||
 | 
			
		||||
            /* OLD WAY STILL VALID 
 | 
			
		||||
            services.AddCommand<EchoCommand, string, EchoCommandHandler>();
 | 
			
		||||
            services.AddTransient<IValidator<EchoCommand>, EchoCommandValidator>();*/
 | 
			
		||||
 | 
			
		||||
            // new way :) with PoweredSoft.CQRS.FluentValidation package.
 | 
			
		||||
            services.AddCommandWithValidator<EchoCommand, string, EchoCommandHandler, EchoCommandValidator>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void AddQueries(IServiceCollection services)
 | 
			
		||||
        {
 | 
			
		||||
            services.AddQuery<PersonQuery, IQueryable<Person>, PersonQueryHandler>();
 | 
			
		||||
            services.AddQuery<OnePersonQuery, Person, OnePersonQueryHandler>();
 | 
			
		||||
            services.AddQuery<ListPersonQuery, List<Person>, ListPersonQueryHandler>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
 | 
			
		||||
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
 | 
			
		||||
        {
 | 
			
		||||
            if (env.IsDevelopment())
 | 
			
		||||
            {
 | 
			
		||||
                app.UseDeveloperExceptionPage();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            app.UseHttpsRedirection();
 | 
			
		||||
 | 
			
		||||
            app.UseCors(o => o.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
 | 
			
		||||
 | 
			
		||||
            app.UseRouting();
 | 
			
		||||
 | 
			
		||||
            app.UseAuthorization();
 | 
			
		||||
 | 
			
		||||
            app.UseSwagger();
 | 
			
		||||
 | 
			
		||||
            // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
 | 
			
		||||
            // specifying the Swagger JSON endpoint.
 | 
			
		||||
            app.UseSwaggerUI(c =>
 | 
			
		||||
            {
 | 
			
		||||
               c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            app.UseEndpoints(endpoints =>
 | 
			
		||||
            {
 | 
			
		||||
                endpoints.MapControllers();
 | 
			
		||||
                endpoints.MapGraphQL();
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,9 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "Logging": {
 | 
			
		||||
    "LogLevel": {
 | 
			
		||||
      "Default": "Information",
 | 
			
		||||
      "Microsoft": "Warning",
 | 
			
		||||
      "Microsoft.Hosting.Lifetime": "Information"
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -1,10 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "Logging": {
 | 
			
		||||
    "LogLevel": {
 | 
			
		||||
      "Default": "Information",
 | 
			
		||||
      "Microsoft": "Warning",
 | 
			
		||||
      "Microsoft.Hosting.Lifetime": "Information"
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "AllowedHosts": "*"
 | 
			
		||||
}
 | 
			
		||||
@ -1,10 +1,8 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.Abstractions.Attributes
 | 
			
		||||
{
 | 
			
		||||
    [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
 | 
			
		||||
    [AttributeUsage(AttributeTargets.Class, Inherited = false)]
 | 
			
		||||
    public class CommandNameAttribute : Attribute
 | 
			
		||||
    {
 | 
			
		||||
        public CommandNameAttribute(string name)
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.Abstractions.Attributes
 | 
			
		||||
{
 | 
			
		||||
    [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
 | 
			
		||||
    [AttributeUsage(AttributeTargets.Class, Inherited = false)]
 | 
			
		||||
    public class QueryNameAttribute : Attribute
 | 
			
		||||
    {
 | 
			
		||||
        public QueryNameAttribute(string name)
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.Abstractions.Discovery
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,4 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.Abstractions.Discovery
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -1,16 +1,15 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.Abstractions
 | 
			
		||||
{
 | 
			
		||||
    public interface ICommandHandler<TCommand>
 | 
			
		||||
    public interface ICommandHandler<in TCommand>
 | 
			
		||||
        where TCommand : class
 | 
			
		||||
    {
 | 
			
		||||
        Task HandleAsync(TCommand command, CancellationToken cancellationToken = default);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public interface ICommandHandler<TCommand, TCommandResult>
 | 
			
		||||
    public interface ICommandHandler<in TCommand, TCommandResult>
 | 
			
		||||
        where TCommand : class
 | 
			
		||||
    {
 | 
			
		||||
        Task<TCommandResult> HandleAsync(TCommand command, CancellationToken cancellationToken = default);
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.Abstractions
 | 
			
		||||
{
 | 
			
		||||
    public interface IQueryHandler<TQuery, TQueryResult>
 | 
			
		||||
    public interface IQueryHandler<in TQuery, TQueryResult>
 | 
			
		||||
        where TQuery : class
 | 
			
		||||
    {
 | 
			
		||||
        Task<TQueryResult> HandleAsync(TQuery query, CancellationToken cancellationToken = default);
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,13 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <TargetFramework>netstandard2.0</TargetFramework>
 | 
			
		||||
    <TargetFramework>netstandard2.1</TargetFramework>
 | 
			
		||||
    <Copyright>Powered Softwares Inc.</Copyright>
 | 
			
		||||
    <PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
 | 
			
		||||
    <Company>PoweredSoft</Company>
 | 
			
		||||
    <Authors>PoweredSoft Team</Authors>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0-rc.1.23419.4" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
</Project>
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,5 @@
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions.Discovery;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.Abstractions
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.AspNetCore.Abstractions.Attributes
 | 
			
		||||
{
 | 
			
		||||
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
 | 
			
		||||
    [AttributeUsage(AttributeTargets.Class, Inherited = false)]
 | 
			
		||||
    public class CommandControllerIgnoreAttribute : Attribute
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,8 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.AspNetCore.Abstractions.Attributes
 | 
			
		||||
{
 | 
			
		||||
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
 | 
			
		||||
    [AttributeUsage(AttributeTargets.Class, Inherited = false)]
 | 
			
		||||
    public class QueryControllerIgnoreAttribute : Attribute
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,9 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <TargetFramework>netstandard2.0</TargetFramework>
 | 
			
		||||
    <TargetFramework>netstandard2.1</TargetFramework>
 | 
			
		||||
    <Copyright>Powered Softwares Inc.</Copyright>
 | 
			
		||||
    <PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
 | 
			
		||||
    <Company>PoweredSoft</Company>
 | 
			
		||||
    <Authors>PoweredSoft Team</Authors>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,6 @@
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.AspNetCore.Mvc
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -11,16 +11,16 @@ namespace PoweredSoft.CQRS.AspNetCore.Mvc
 | 
			
		||||
{
 | 
			
		||||
    public class CommandControllerAsyncAuthorizationFilter : IAsyncAuthorizationFilter
 | 
			
		||||
    {
 | 
			
		||||
        private readonly ICommandAuthorizationService _authorizationService;
 | 
			
		||||
        private readonly ICommandAuthorizationService authorizationService;
 | 
			
		||||
 | 
			
		||||
        public CommandControllerAsyncAuthorizationFilter(IServiceProvider serviceProvider)
 | 
			
		||||
        {
 | 
			
		||||
            _authorizationService = serviceProvider.GetService<ICommandAuthorizationService>();
 | 
			
		||||
            authorizationService = serviceProvider.GetService<ICommandAuthorizationService>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
 | 
			
		||||
        {
 | 
			
		||||
            if (_authorizationService == null)
 | 
			
		||||
            if (authorizationService == null)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            var action = context.ActionDescriptor as Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor;
 | 
			
		||||
@ -34,7 +34,7 @@ namespace PoweredSoft.CQRS.AspNetCore.Mvc
 | 
			
		||||
            else
 | 
			
		||||
                commandType = action.ControllerTypeInfo.GenericTypeArguments.First();
 | 
			
		||||
 | 
			
		||||
            var ar = await _authorizationService.IsAllowedAsync(commandType);
 | 
			
		||||
            var ar = await authorizationService.IsAllowedAsync(commandType);
 | 
			
		||||
            if (ar == AuthorizationResult.Forbidden)
 | 
			
		||||
                context.Result = new StatusCodeResult(403);
 | 
			
		||||
            else if(ar == AuthorizationResult.Unauthorized)
 | 
			
		||||
 | 
			
		||||
@ -16,13 +16,19 @@ namespace PoweredSoft.CQRS.AspNetCore.Mvc
 | 
			
		||||
 | 
			
		||||
        public void Apply(ControllerModel controller)
 | 
			
		||||
        {
 | 
			
		||||
            if (controller.ControllerType.IsGenericType && controller.ControllerType.Name.Contains("CommandController") && controller.ControllerType.Assembly == typeof(CommandControllerConvention).Assembly)
 | 
			
		||||
            {
 | 
			
		||||
                var genericType = controller.ControllerType.GenericTypeArguments[0];
 | 
			
		||||
                var commandDiscovery = this.serviceProvider.GetRequiredService<ICommandDiscovery>();
 | 
			
		||||
                var command = commandDiscovery.FindCommand(genericType);
 | 
			
		||||
                controller.ControllerName = command.LowerCamelCaseName;
 | 
			
		||||
            }
 | 
			
		||||
            if (!controller.ControllerType.IsGenericType)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            if (!controller.ControllerType.Name.Contains("CommandController"))
 | 
			
		||||
                return;
 | 
			
		||||
            
 | 
			
		||||
            if (controller.ControllerType.Assembly != typeof(CommandControllerConvention).Assembly)
 | 
			
		||||
                return;
 | 
			
		||||
                
 | 
			
		||||
            var genericType = controller.ControllerType.GenericTypeArguments[0];
 | 
			
		||||
            var commandDiscovery = this.serviceProvider.GetRequiredService<ICommandDiscovery>();
 | 
			
		||||
            var command = commandDiscovery.FindCommand(genericType);
 | 
			
		||||
            controller.ControllerName = command.LowerCamelCaseName;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,10 @@
 | 
			
		||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc.Controllers;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions.Discovery;
 | 
			
		||||
using PoweredSoft.CQRS.AspNetCore.Abstractions.Attributes;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.AspNetCore.Mvc
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,6 @@
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.AspNetCore.Mvc
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -11,16 +11,16 @@ namespace PoweredSoft.CQRS.AspNetCore.Mvc
 | 
			
		||||
{
 | 
			
		||||
    public class QueryControllerAsyncAuthorizationFilter : IAsyncAuthorizationFilter
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IQueryAuthorizationService _authorizationService;
 | 
			
		||||
        private readonly IQueryAuthorizationService authorizationService;
 | 
			
		||||
 | 
			
		||||
        public QueryControllerAsyncAuthorizationFilter(IServiceProvider serviceProvider)
 | 
			
		||||
        {
 | 
			
		||||
            _authorizationService = serviceProvider.GetService<IQueryAuthorizationService>();
 | 
			
		||||
            authorizationService = serviceProvider.GetService<IQueryAuthorizationService>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
 | 
			
		||||
        {
 | 
			
		||||
            if (_authorizationService == null)
 | 
			
		||||
            if (authorizationService == null)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            var action = context.ActionDescriptor as Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor;
 | 
			
		||||
@ -34,7 +34,7 @@ namespace PoweredSoft.CQRS.AspNetCore.Mvc
 | 
			
		||||
            else
 | 
			
		||||
                queryType = action.ControllerTypeInfo.GenericTypeArguments.First();
 | 
			
		||||
 | 
			
		||||
            var ar = await _authorizationService.IsAllowedAsync(queryType);
 | 
			
		||||
            var ar = await authorizationService.IsAllowedAsync(queryType);
 | 
			
		||||
            if (ar == AuthorizationResult.Forbidden)
 | 
			
		||||
                context.Result = new StatusCodeResult(403);
 | 
			
		||||
            else if (ar == AuthorizationResult.Unauthorized)
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,10 @@
 | 
			
		||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc.Controllers;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions.Discovery;
 | 
			
		||||
using PoweredSoft.CQRS.AspNetCore.Abstractions.Attributes;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.AspNetCore.Mvc
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,4 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.AspNetCore.Mvc
 | 
			
		||||
namespace PoweredSoft.CQRS.AspNetCore.Mvc
 | 
			
		||||
{
 | 
			
		||||
    public class QueryControllerOptions
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,12 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <TargetFrameworks>netcoreapp3.1;net5.0</TargetFrameworks>
 | 
			
		||||
    <TargetFramework>net8.0</TargetFramework>
 | 
			
		||||
    <Copyright>Powered Softwares Inc.</Copyright>
 | 
			
		||||
    <PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
 | 
			
		||||
    <Company>PoweredSoft</Company>
 | 
			
		||||
    <Authors>PoweredSoft Team</Authors>
 | 
			
		||||
    <IsAotCompatible>true</IsAotCompatible>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,4 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,5 @@
 | 
			
		||||
using PoweredSoft.DynamicQuery.Core;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using PoweredSoft.DynamicQuery.Core;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.DynamicQuery.Abstractions
 | 
			
		||||
{
 | 
			
		||||
@ -12,7 +10,7 @@ namespace PoweredSoft.CQRS.DynamicQuery.Abstractions
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public interface IDynamicQuery<TSource, TDestination, TParams> : IDynamicQuery<TSource, TDestination>, IDynamicQueryParams<TParams>
 | 
			
		||||
    public interface IDynamicQuery<TSource, TDestination, out TParams> : IDynamicQuery<TSource, TDestination>, IDynamicQueryParams<TParams>
 | 
			
		||||
        where TSource : class
 | 
			
		||||
        where TDestination : class
 | 
			
		||||
        where TParams : class
 | 
			
		||||
@ -21,7 +19,6 @@ namespace PoweredSoft.CQRS.DynamicQuery.Abstractions
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public interface IDynamicQuery
 | 
			
		||||
        
 | 
			
		||||
    {
 | 
			
		||||
        List<IFilter> GetFilters();
 | 
			
		||||
        List<IGroup> GetGroups();
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,5 @@
 | 
			
		||||
using PoweredSoft.DynamicQuery.Core;
 | 
			
		||||
using System;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.DynamicQuery.Abstractions
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
namespace PoweredSoft.CQRS.DynamicQuery.Abstractions
 | 
			
		||||
{
 | 
			
		||||
    public interface IDynamicQueryParams<TParams>
 | 
			
		||||
    public interface IDynamicQueryParams<out TParams>
 | 
			
		||||
        where TParams : class
 | 
			
		||||
    {
 | 
			
		||||
        TParams GetParams();
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,4 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
@ -9,6 +6,6 @@ namespace PoweredSoft.CQRS.DynamicQuery.Abstractions
 | 
			
		||||
{
 | 
			
		||||
    public interface IQueryableProvider<TSource>
 | 
			
		||||
    {
 | 
			
		||||
        Task<IQueryable<TSource>> GetQueryableAsync(object query, CancellationToken cancelllationToken = default);
 | 
			
		||||
        Task<IQueryable<TSource>> GetQueryableAsync(object query, CancellationToken cancellationToken = default);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,6 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <TargetFramework>netstandard2.0</TargetFramework>
 | 
			
		||||
    <TargetFramework>netstandard2.1</TargetFramework>
 | 
			
		||||
    <Copyright>Powered Softwares Inc.</Copyright>
 | 
			
		||||
    <PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
 | 
			
		||||
    <Company>PoweredSoft</Company>
 | 
			
		||||
@ -11,5 +10,4 @@
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="PoweredSoft.DynamicQuery.Core" Version="3.0.1" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,8 @@
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
 | 
			
		||||
using PoweredSoft.DynamicQuery;
 | 
			
		||||
using PoweredSoft.DynamicQuery.Core;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,10 @@
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using PoweredSoft.DynamicQuery;
 | 
			
		||||
using PoweredSoft.DynamicQuery.Core;
 | 
			
		||||
using System;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text.Json;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using PoweredSoft.DynamicQuery;
 | 
			
		||||
using PoweredSoft.DynamicQuery.Core;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore
 | 
			
		||||
{
 | 
			
		||||
@ -49,18 +49,29 @@ namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore
 | 
			
		||||
            object value = Value;
 | 
			
		||||
            if (Value is JsonElement jsonElement)
 | 
			
		||||
            {
 | 
			
		||||
                if (jsonElement.ValueKind == JsonValueKind.String)
 | 
			
		||||
                    value = jsonElement.ToString();
 | 
			
		||||
                else if (jsonElement.ValueKind == JsonValueKind.Number && jsonElement.TryGetInt64(out var l))
 | 
			
		||||
                    value = l;
 | 
			
		||||
                else if (jsonElement.ValueKind == JsonValueKind.True)
 | 
			
		||||
                    value = true;
 | 
			
		||||
                else if (jsonElement.ValueKind == JsonValueKind.False)
 | 
			
		||||
                    value = false;
 | 
			
		||||
                else if (jsonElement.ValueKind == JsonValueKind.Array)
 | 
			
		||||
                    throw new System.Exception("TODO");
 | 
			
		||||
                else
 | 
			
		||||
                    value = null;
 | 
			
		||||
                switch (jsonElement.ValueKind)
 | 
			
		||||
                {
 | 
			
		||||
                    case JsonValueKind.String:
 | 
			
		||||
                        value = jsonElement.ToString();
 | 
			
		||||
                        break;
 | 
			
		||||
                    case JsonValueKind.Number:
 | 
			
		||||
                        if (jsonElement.ToString().Contains('.'))
 | 
			
		||||
                            value = jsonElement.GetDecimal();
 | 
			
		||||
                        else if (jsonElement.TryGetInt64(out var convertedValue))
 | 
			
		||||
                            value = convertedValue;
 | 
			
		||||
                        break;
 | 
			
		||||
                    case JsonValueKind.True:
 | 
			
		||||
                        value = true;
 | 
			
		||||
                        break;
 | 
			
		||||
                    case JsonValueKind.False:
 | 
			
		||||
                        value = false;
 | 
			
		||||
                        break;
 | 
			
		||||
                    // TODO: Array support
 | 
			
		||||
                    default:
 | 
			
		||||
                        value = null;
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var simpleFilter = new SimpleFilter
 | 
			
		||||
 | 
			
		||||
@ -1,23 +1,21 @@
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions;
 | 
			
		||||
using PoweredSoft.CQRS.AspNetCore.Mvc;
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
 | 
			
		||||
using PoweredSoft.DynamicQuery.Core;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
 | 
			
		||||
{
 | 
			
		||||
    [ApiController, Route("api/query/[controller]")]
 | 
			
		||||
    public class DynamicQueryController<TUnderlyingQuery, TSource, TDestination> : Controller
 | 
			
		||||
    public class DynamicQueryController<TSource, TDestination> : Controller
 | 
			
		||||
        where TSource : class
 | 
			
		||||
        where TDestination : class
 | 
			
		||||
    {
 | 
			
		||||
        [HttpPost, QueryControllerAuthorization]
 | 
			
		||||
        public async Task<IQueryExecutionResult<TDestination>> HandleAsync(
 | 
			
		||||
                [FromBody] DynamicQuery<TSource, TDestination> query, 
 | 
			
		||||
                [FromServices]PoweredSoft.CQRS.Abstractions.IQueryHandler<IDynamicQuery<TSource, TDestination>, IQueryExecutionResult<TDestination>> queryHandler
 | 
			
		||||
                [FromServices]IQueryHandler<IDynamicQuery<TSource, TDestination>, IQueryExecutionResult<TDestination>> queryHandler
 | 
			
		||||
            )
 | 
			
		||||
        {
 | 
			
		||||
            var result = await queryHandler.HandleAsync(query, HttpContext.RequestAborted);
 | 
			
		||||
@ -27,7 +25,7 @@ namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
 | 
			
		||||
        [HttpGet, QueryControllerAuthorization]
 | 
			
		||||
        public async Task<IQueryExecutionResult<TDestination>> HandleGetAsync(
 | 
			
		||||
                [FromQuery] DynamicQuery<TSource, TDestination> query,
 | 
			
		||||
                [FromServices] PoweredSoft.CQRS.Abstractions.IQueryHandler<IDynamicQuery<TSource, TDestination>, IQueryExecutionResult<TDestination>> queryHandler
 | 
			
		||||
                [FromServices] IQueryHandler<IDynamicQuery<TSource, TDestination>, IQueryExecutionResult<TDestination>> queryHandler
 | 
			
		||||
            )
 | 
			
		||||
        {
 | 
			
		||||
            var result = await queryHandler.HandleAsync(query, HttpContext.RequestAborted);
 | 
			
		||||
@ -36,7 +34,7 @@ namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [ApiController, Route("api/query/[controller]")]
 | 
			
		||||
    public class DynamicQueryController<TUnderlyingQuery, TSource, TDestination, TParams> : Controller
 | 
			
		||||
    public class DynamicQueryController<TSource, TDestination, TParams> : Controller
 | 
			
		||||
        where TSource : class
 | 
			
		||||
        where TDestination : class
 | 
			
		||||
        where TParams : class
 | 
			
		||||
@ -44,7 +42,7 @@ namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
 | 
			
		||||
        [HttpPost, QueryControllerAuthorization]
 | 
			
		||||
        public async Task<IQueryExecutionResult<TDestination>> HandleAsync(
 | 
			
		||||
                [FromBody] DynamicQuery<TSource, TDestination, TParams> query,
 | 
			
		||||
                [FromServices] PoweredSoft.CQRS.Abstractions.IQueryHandler<IDynamicQuery<TSource, TDestination, TParams>, IQueryExecutionResult<TDestination>> queryHandler
 | 
			
		||||
                [FromServices] IQueryHandler<IDynamicQuery<TSource, TDestination, TParams>, IQueryExecutionResult<TDestination>> queryHandler
 | 
			
		||||
            )
 | 
			
		||||
        {
 | 
			
		||||
            var result = await queryHandler.HandleAsync(query, HttpContext.RequestAborted);
 | 
			
		||||
@ -54,7 +52,7 @@ namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
 | 
			
		||||
        [HttpGet, QueryControllerAuthorization]
 | 
			
		||||
        public async Task<IQueryExecutionResult<TDestination>> HandleGetAsync(
 | 
			
		||||
                [FromQuery] DynamicQuery<TSource, TDestination, TParams> query,
 | 
			
		||||
                [FromServices] PoweredSoft.CQRS.Abstractions.IQueryHandler<IDynamicQuery<TSource, TDestination, TParams>, IQueryExecutionResult<TDestination>> queryHandler
 | 
			
		||||
                [FromServices] IQueryHandler<IDynamicQuery<TSource, TDestination, TParams>, IQueryExecutionResult<TDestination>> queryHandler
 | 
			
		||||
            )
 | 
			
		||||
        {
 | 
			
		||||
            var result = await queryHandler.HandleAsync(query, HttpContext.RequestAborted);
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,7 @@
 | 
			
		||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
 | 
			
		||||
using System;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions.Discovery;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,11 @@
 | 
			
		||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc.Controllers;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions.Discovery;
 | 
			
		||||
using PoweredSoft.CQRS.AspNetCore.Abstractions.Attributes;
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery.Discover;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
 | 
			
		||||
{
 | 
			
		||||
@ -36,13 +34,13 @@ namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
 | 
			
		||||
                {
 | 
			
		||||
                    if (dynamicQueryMeta.ParamsType == null)
 | 
			
		||||
                    {
 | 
			
		||||
                        var controllerType = typeof(DynamicQueryController<,,>).MakeGenericType(f.QueryType, dynamicQueryMeta.SourceType, dynamicQueryMeta.DestinationType);
 | 
			
		||||
                        var controllerType = typeof(DynamicQueryController<,>).MakeGenericType(f.QueryType, dynamicQueryMeta.SourceType, dynamicQueryMeta.DestinationType);
 | 
			
		||||
                        var controllerTypeInfo = controllerType.GetTypeInfo();
 | 
			
		||||
                        feature.Controllers.Add(controllerTypeInfo);
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        var controllerType = typeof(DynamicQueryController<,,,>).MakeGenericType(f.QueryType, dynamicQueryMeta.SourceType, dynamicQueryMeta.DestinationType, dynamicQueryMeta.ParamsType);
 | 
			
		||||
                        var controllerType = typeof(DynamicQueryController<,,>).MakeGenericType(f.QueryType, dynamicQueryMeta.SourceType, dynamicQueryMeta.DestinationType, dynamicQueryMeta.ParamsType);
 | 
			
		||||
                        var controllerTypeInfo = controllerType.GetTypeInfo();
 | 
			
		||||
                        feature.Controllers.Add(controllerTypeInfo);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,4 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
 | 
			
		||||
namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
 | 
			
		||||
{
 | 
			
		||||
    public class DynamicQueryControllerOptions
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,6 @@
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
 | 
			
		||||
using System;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc;
 | 
			
		||||
using PoweredSoft.DynamicQuery.Core;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,11 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <TargetFrameworks>netcoreapp3.1;net5.0</TargetFrameworks>
 | 
			
		||||
    <TargetFramework>net8.0</TargetFramework>
 | 
			
		||||
    <Copyright>Powered Softwares Inc.</Copyright>
 | 
			
		||||
    <PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
 | 
			
		||||
    <Company>PoweredSoft</Company>
 | 
			
		||||
    <Authors>PoweredSoft Team</Authors>
 | 
			
		||||
    <IsAotCompatible>true</IsAotCompatible>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
@ -19,5 +19,4 @@
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS.DynamicQuery.Abstractions\PoweredSoft.CQRS.DynamicQuery.Abstractions.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS.DynamicQuery\PoweredSoft.CQRS.DynamicQuery.csproj" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,6 @@
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions.Discovery;
 | 
			
		||||
using PoweredSoft.CQRS.Discovery;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System;
 | 
			
		||||
using Pluralize.NET;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions.Discovery;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.DynamicQuery.Discover
 | 
			
		||||
{
 | 
			
		||||
@ -23,7 +21,7 @@ namespace PoweredSoft.CQRS.DynamicQuery.Discover
 | 
			
		||||
                if (OverridableName != null)
 | 
			
		||||
                    return OverridableName;
 | 
			
		||||
 | 
			
		||||
                var pluralizer = new Pluralize.NET.Pluralizer();
 | 
			
		||||
                var pluralizer = new Pluralizer();
 | 
			
		||||
                return pluralizer.Pluralize(DestinationType.Name);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -83,8 +83,8 @@ namespace PoweredSoft.CQRS.DynamicQuery
 | 
			
		||||
                PageSize = query?.GetPageSize(),
 | 
			
		||||
                Filters = query?.GetFilters() ?? new List<IFilter>(),
 | 
			
		||||
                Sorts = query?.GetSorts() ?? new List<ISort>(),
 | 
			
		||||
                Groups = query.GetGroups() ?? new List<IGroup>(),
 | 
			
		||||
                Aggregates = query.GetAggregates() ?? new List<IAggregate>()
 | 
			
		||||
                Groups = query?.GetGroups() ?? new List<IGroup>(),
 | 
			
		||||
                Aggregates = query?.GetAggregates() ?? new List<IAggregate>()
 | 
			
		||||
            };
 | 
			
		||||
            return criteria;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,6 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <TargetFramework>netstandard2.0</TargetFramework>
 | 
			
		||||
    <TargetFramework>netstandard2.1</TargetFramework>
 | 
			
		||||
    <Copyright>Powered Softwares Inc.</Copyright>
 | 
			
		||||
    <PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
 | 
			
		||||
    <Company>PoweredSoft</Company>
 | 
			
		||||
@ -17,5 +16,4 @@
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS.DynamicQuery.Abstractions\PoweredSoft.CQRS.DynamicQuery.Abstractions.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS\PoweredSoft.CQRS.csproj" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
 | 
			
		||||
@ -5,9 +5,6 @@ using PoweredSoft.CQRS.Abstractions.Discovery;
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery.Discover;
 | 
			
		||||
using PoweredSoft.DynamicQuery.Core;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.DynamicQuery
 | 
			
		||||
{
 | 
			
		||||
@ -22,7 +19,7 @@ namespace PoweredSoft.CQRS.DynamicQuery
 | 
			
		||||
            where TDestination : class
 | 
			
		||||
        {
 | 
			
		||||
            // add query handler.
 | 
			
		||||
            services.AddTransient<PoweredSoft.CQRS.Abstractions.IQueryHandler<IDynamicQuery<TSource, TDestination>, IQueryExecutionResult<TDestination>>, DynamicQueryHandler<TSource, TDestination>>();
 | 
			
		||||
            services.AddTransient<IQueryHandler<IDynamicQuery<TSource, TDestination>, IQueryExecutionResult<TDestination>>, DynamicQueryHandler<TSource, TDestination>>();
 | 
			
		||||
 | 
			
		||||
            // add for discovery purposes.
 | 
			
		||||
            var queryType = typeof(IDynamicQuery<TSource, TDestination>);
 | 
			
		||||
@ -68,7 +65,7 @@ namespace PoweredSoft.CQRS.DynamicQuery
 | 
			
		||||
            where TParams : class
 | 
			
		||||
        {
 | 
			
		||||
            // add query handler.
 | 
			
		||||
            services.AddTransient<PoweredSoft.CQRS.Abstractions.IQueryHandler<IDynamicQuery<TSource, TDestination, TParams>, IQueryExecutionResult<TDestination>>, DynamicQueryHandler<TSource, TDestination, TParams>>();
 | 
			
		||||
            services.AddTransient<IQueryHandler<IDynamicQuery<TSource, TDestination, TParams>, IQueryExecutionResult<TDestination>>, DynamicQueryHandler<TSource, TDestination, TParams>>();
 | 
			
		||||
 | 
			
		||||
            // add for discovery purposes.
 | 
			
		||||
            var queryType = typeof(IDynamicQuery<TSource, TDestination, TParams>);
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,6 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <TargetFramework>netstandard2.0</TargetFramework>
 | 
			
		||||
    <TargetFramework>netstandard2.1</TargetFramework>
 | 
			
		||||
    <Copyright>Powered Softwares Inc.</Copyright>
 | 
			
		||||
    <PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
 | 
			
		||||
    <Company>PoweredSoft</Company>
 | 
			
		||||
@ -9,11 +8,10 @@
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="FluentValidation" Version="10.3.0" />
 | 
			
		||||
    <PackageReference Include="FluentValidation" Version="10.4.0" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS\PoweredSoft.CQRS.csproj" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,6 @@
 | 
			
		||||
using FluentValidation;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection.Extensions;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions.Discovery;
 | 
			
		||||
using PoweredSoft.CQRS.Discovery;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.FluentValidation
 | 
			
		||||
{
 | 
			
		||||
@ -19,7 +13,7 @@ namespace PoweredSoft.CQRS.FluentValidation
 | 
			
		||||
            return services;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IServiceCollection AddCommandWithValidator<TCommand, TCommandHandler, TValidator>(this IServiceCollection services)
 | 
			
		||||
        public static IServiceCollection AddCommand<TCommand, TCommandHandler, TValidator>(this IServiceCollection services)
 | 
			
		||||
            where TCommand : class
 | 
			
		||||
            where TCommandHandler : class, ICommandHandler<TCommand>
 | 
			
		||||
            where TValidator : class, IValidator<TCommand>
 | 
			
		||||
@ -28,7 +22,7 @@ namespace PoweredSoft.CQRS.FluentValidation
 | 
			
		||||
                .AddFluentValidator<TCommand, TValidator>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IServiceCollection AddCommandWithValidator<TCommand, TCommandResult, TCommandHandler, TValidator>(this IServiceCollection services)
 | 
			
		||||
        public static IServiceCollection AddCommand<TCommand, TCommandResult, TCommandHandler, TValidator>(this IServiceCollection services)
 | 
			
		||||
            where TCommand : class
 | 
			
		||||
            where TCommandHandler : class, ICommandHandler<TCommand, TCommandResult>
 | 
			
		||||
            where TValidator : class, IValidator<TCommand>
 | 
			
		||||
@ -37,7 +31,7 @@ namespace PoweredSoft.CQRS.FluentValidation
 | 
			
		||||
               .AddFluentValidator<TCommand, TValidator>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IServiceCollection AddQueryWithValidator<TQuery, TQueryResult, TQueryHandler, TValidator>(this IServiceCollection services)
 | 
			
		||||
        public static IServiceCollection AddQuery<TQuery, TQueryResult, TQueryHandler, TValidator>(this IServiceCollection services)
 | 
			
		||||
            where TQuery : class
 | 
			
		||||
            where TQueryHandler : class, IQueryHandler<TQuery, TQueryResult>
 | 
			
		||||
            where TValidator : class, IValidator<TQuery>
 | 
			
		||||
 | 
			
		||||
@ -1,10 +0,0 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.Abstractions
 | 
			
		||||
{
 | 
			
		||||
    public interface IGraphQLFieldError
 | 
			
		||||
    {
 | 
			
		||||
        string Field { get; set; }
 | 
			
		||||
        List<string> Errors { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,11 +0,0 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.Abstractions
 | 
			
		||||
{
 | 
			
		||||
    public interface IGraphQLValidationResult
 | 
			
		||||
    {
 | 
			
		||||
        bool IsValid { get; }
 | 
			
		||||
 | 
			
		||||
        List<IGraphQLFieldError> Errors { get; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,13 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.Abstractions
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    public interface IGraphQLValidationService
 | 
			
		||||
    {
 | 
			
		||||
        Task<IGraphQLValidationResult> ValidateObjectAsync(object subject, CancellationToken cancellationToken = default);
 | 
			
		||||
        Task<IGraphQLValidationResult> ValidateAsync<T>(T subject, CancellationToken cancellationToken = default);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,11 +0,0 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <TargetFramework>netstandard2.0</TargetFramework>
 | 
			
		||||
    <Copyright>Powered Softwares Inc.</Copyright>
 | 
			
		||||
    <PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
 | 
			
		||||
    <Company>PoweredSoft</Company>
 | 
			
		||||
    <Authors>PoweredSoft Team</Authors>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
@ -1,21 +0,0 @@
 | 
			
		||||
using PoweredSoft.DynamicQuery;
 | 
			
		||||
using PoweredSoft.DynamicQuery.Core;
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL
 | 
			
		||||
{
 | 
			
		||||
    public class GraphQLAdvanceQueryAggregate
 | 
			
		||||
    {
 | 
			
		||||
        public string Path { get; set; }
 | 
			
		||||
        public AggregateType Type { get; set; }
 | 
			
		||||
 | 
			
		||||
        internal IAggregate ToAggregate()
 | 
			
		||||
        {
 | 
			
		||||
            return new Aggregate
 | 
			
		||||
            {
 | 
			
		||||
                Path = Path,
 | 
			
		||||
                Type = Type
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,51 +0,0 @@
 | 
			
		||||
using PoweredSoft.DynamicQuery;
 | 
			
		||||
using PoweredSoft.DynamicQuery.Core;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.DynamicQuery
 | 
			
		||||
{
 | 
			
		||||
    public class GraphQLAdvanceQueryFilter
 | 
			
		||||
    {
 | 
			
		||||
        public bool? And { get; set; }
 | 
			
		||||
        public FilterType Type { get; set; }
 | 
			
		||||
        public bool? CaseInsensitive { get; set; }
 | 
			
		||||
        public string Path { get; set; }
 | 
			
		||||
        public GraphQLVariantInput Value { get; set; }
 | 
			
		||||
        public bool? Not { get; set; }
 | 
			
		||||
 | 
			
		||||
        public List<GraphQLAdvanceQueryFilter> Filters { get; set; }
 | 
			
		||||
 | 
			
		||||
        internal IFilter ToFilter()
 | 
			
		||||
        {
 | 
			
		||||
            if (Type == FilterType.Composite)
 | 
			
		||||
            {
 | 
			
		||||
                var ret = new CompositeFilter
 | 
			
		||||
                {
 | 
			
		||||
                    And = And,
 | 
			
		||||
                    Type = FilterType.Composite
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                if (Filters == null)
 | 
			
		||||
                    ret.Filters = new List<IFilter>();
 | 
			
		||||
                else
 | 
			
		||||
                    ret.Filters = Filters.Select(t => t.ToFilter()).ToList();
 | 
			
		||||
 | 
			
		||||
                return ret;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                return new SimpleFilter
 | 
			
		||||
                {
 | 
			
		||||
                    And = And,
 | 
			
		||||
                    CaseInsensitive = CaseInsensitive,
 | 
			
		||||
                    Type = Type,
 | 
			
		||||
                    Not = Not,
 | 
			
		||||
                    Path = Path,
 | 
			
		||||
                    Value = Value.GetRawObjectValue()
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,21 +0,0 @@
 | 
			
		||||
using PoweredSoft.DynamicQuery;
 | 
			
		||||
using PoweredSoft.DynamicQuery.Core;
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL
 | 
			
		||||
{
 | 
			
		||||
    public class GraphQLAdvanceQueryGroup 
 | 
			
		||||
    {
 | 
			
		||||
        public string Path { get; set; }
 | 
			
		||||
        public bool? Ascending { get; set; }
 | 
			
		||||
 | 
			
		||||
        internal IGroup ToGroup()
 | 
			
		||||
        {
 | 
			
		||||
            return new Group
 | 
			
		||||
            {
 | 
			
		||||
                Path = Path,
 | 
			
		||||
                Ascending = Ascending
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,11 +0,0 @@
 | 
			
		||||
using PoweredSoft.DynamicQuery.Core;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.DynamicQuery
 | 
			
		||||
{
 | 
			
		||||
    public class GraphQLAggregateResult
 | 
			
		||||
    {
 | 
			
		||||
        public string Path { get; set; }
 | 
			
		||||
        public AggregateType Type { get; set; }
 | 
			
		||||
        public GraphQLVariantResult Value { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,73 +0,0 @@
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
 | 
			
		||||
using PoweredSoft.CQRS.GraphQL.DynamicQuery;
 | 
			
		||||
using PoweredSoft.DynamicQuery.Core;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.DynamicQuery
 | 
			
		||||
{
 | 
			
		||||
    public class GraphQLDynamicQuery<TSource, TDestination> : GraphQLDynamicQuery, IDynamicQuery<TSource, TDestination>
 | 
			
		||||
        where TSource : class
 | 
			
		||||
        where TDestination : class
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class GraphQLDynamicQuery<TSource, TDestination, TParams> : GraphQLDynamicQuery<TSource, TDestination>,
 | 
			
		||||
        IDynamicQuery<TSource, TDestination, TParams>
 | 
			
		||||
        where TSource : class
 | 
			
		||||
        where TDestination : class
 | 
			
		||||
        where TParams : class
 | 
			
		||||
    {
 | 
			
		||||
        public TParams Params { get; set; }
 | 
			
		||||
 | 
			
		||||
        public TParams GetParams() => Params;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class GraphQLDynamicQuery : IDynamicQuery
 | 
			
		||||
    {
 | 
			
		||||
        public int? Page { get; set; }
 | 
			
		||||
        public int? PageSize { get; set; }
 | 
			
		||||
 | 
			
		||||
        public List<GraphQLSort> Sorts { get; set; }
 | 
			
		||||
        public List<GraphQLAdvanceQueryFilter> Filters { get; set; }
 | 
			
		||||
        public List<GraphQLAdvanceQueryGroup> Groups { get; set; }
 | 
			
		||||
        public List<GraphQLAdvanceQueryAggregate> Aggregates { get; set; }
 | 
			
		||||
 | 
			
		||||
        public List<IAggregate> GetAggregates()
 | 
			
		||||
        {
 | 
			
		||||
            if (Aggregates == null)
 | 
			
		||||
                return new List<IAggregate>();
 | 
			
		||||
 | 
			
		||||
            return Aggregates.Select(a => a.ToAggregate()).ToList();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<IFilter> GetFilters()
 | 
			
		||||
        {
 | 
			
		||||
            if (Filters == null)
 | 
			
		||||
                return new List<IFilter>();
 | 
			
		||||
 | 
			
		||||
            return Filters.Select(t => t.ToFilter()).ToList();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<IGroup> GetGroups()
 | 
			
		||||
        {
 | 
			
		||||
            if (Groups == null)
 | 
			
		||||
                return new List<IGroup>();
 | 
			
		||||
 | 
			
		||||
            return Groups.Select(t => t.ToGroup()).ToList();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int? GetPage() => Page;
 | 
			
		||||
 | 
			
		||||
        public int? GetPageSize() => PageSize;
 | 
			
		||||
 | 
			
		||||
        public List<ISort> GetSorts()
 | 
			
		||||
        {
 | 
			
		||||
            if (Sorts == null)
 | 
			
		||||
                return new List<ISort>();
 | 
			
		||||
 | 
			
		||||
            return Sorts.Select(t => t.ToSort()).ToList();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,59 +0,0 @@
 | 
			
		||||
using PoweredSoft.DynamicQuery.Core;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.DynamicQuery
 | 
			
		||||
{
 | 
			
		||||
    public class GraphQLDynamicQueryExecutionResult<TResult> : GraphQLDynamicQueryResult<TResult>
 | 
			
		||||
    {
 | 
			
		||||
        public List<GraphQLDynamicQueryGroupResult<TResult>> Groups { get; set; }
 | 
			
		||||
        public long TotalRecords { get; set; }
 | 
			
		||||
        public long? NumberOfPages { get; set; }
 | 
			
		||||
 | 
			
		||||
        public void FromResult(IQueryExecutionResult<TResult> queryResult)
 | 
			
		||||
        {
 | 
			
		||||
            TotalRecords = queryResult.TotalRecords;
 | 
			
		||||
            NumberOfPages = queryResult.NumberOfPages;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            if (queryResult.Aggregates != null)
 | 
			
		||||
                Aggregates = queryResult.Aggregates.Select(ConvertAggregateResult).ToList();
 | 
			
		||||
 | 
			
		||||
            if (queryResult.Data != null)
 | 
			
		||||
                Data = queryResult.Data;
 | 
			
		||||
 | 
			
		||||
            if (queryResult is IQueryExecutionGroupResult<TResult> groupedResult)
 | 
			
		||||
                Groups = groupedResult.Groups.Select(ConvertGroupResult).ToList();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected virtual GraphQLDynamicQueryGroupResult<TResult> ConvertGroupResult(IGroupQueryResult<TResult> arg)
 | 
			
		||||
        {
 | 
			
		||||
            var group = new GraphQLDynamicQueryGroupResult<TResult>();
 | 
			
		||||
 | 
			
		||||
            group.GroupPath = arg.GroupPath;
 | 
			
		||||
            group.GroupValue = new GraphQLVariantResult(arg.GroupValue);
 | 
			
		||||
 | 
			
		||||
            if (arg.Data != null)
 | 
			
		||||
                group.Data = arg.Data;
 | 
			
		||||
 | 
			
		||||
            if (arg.Aggregates != null)
 | 
			
		||||
                group.Aggregates = arg.Aggregates.Select(ConvertAggregateResult).ToList();
 | 
			
		||||
 | 
			
		||||
            if (arg.HasSubGroups)
 | 
			
		||||
                group.SubGroups = arg.SubGroups.Select(ConvertGroupResult).ToList();
 | 
			
		||||
 | 
			
		||||
            return group;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected virtual GraphQLAggregateResult ConvertAggregateResult(IAggregateResult arg)
 | 
			
		||||
        {
 | 
			
		||||
            return new GraphQLAggregateResult
 | 
			
		||||
            {
 | 
			
		||||
                Path = arg.Path,
 | 
			
		||||
                Type = arg.Type,
 | 
			
		||||
                Value = new GraphQLVariantResult(arg.Value)
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,13 +0,0 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.DynamicQuery
 | 
			
		||||
{
 | 
			
		||||
    public class GraphQLDynamicQueryGroupResult<TResult> : GraphQLDynamicQueryResult<TResult>
 | 
			
		||||
    {
 | 
			
		||||
        public string GroupPath { get; set; }
 | 
			
		||||
        public GraphQLVariantResult GroupValue { get; set; }
 | 
			
		||||
        public bool HasSubGroups => SubGroups?.Any() == true;
 | 
			
		||||
        public List<GraphQLDynamicQueryGroupResult<TResult>> SubGroups { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,10 +0,0 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.DynamicQuery
 | 
			
		||||
{
 | 
			
		||||
    public class GraphQLDynamicQueryResult<TResult>
 | 
			
		||||
    {
 | 
			
		||||
        public List<TResult> Data { get; set; }
 | 
			
		||||
        public List<GraphQLAggregateResult> Aggregates { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,17 +0,0 @@
 | 
			
		||||
using PoweredSoft.DynamicQuery;
 | 
			
		||||
using PoweredSoft.DynamicQuery.Core;
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.DynamicQuery
 | 
			
		||||
{
 | 
			
		||||
    public class GraphQLSort
 | 
			
		||||
    {
 | 
			
		||||
        public string Path { get; set; }
 | 
			
		||||
        public bool? Ascending { get; set; }
 | 
			
		||||
 | 
			
		||||
        internal ISort ToSort()
 | 
			
		||||
        {
 | 
			
		||||
            return new Sort(Path, Ascending);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,90 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.DynamicQuery
 | 
			
		||||
{
 | 
			
		||||
    public abstract class GraphQLVariant
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        protected virtual string ResolveTypeName(object value)
 | 
			
		||||
        {
 | 
			
		||||
            if (value != null)
 | 
			
		||||
            {
 | 
			
		||||
                if (value is int)
 | 
			
		||||
                    return "int";
 | 
			
		||||
                if (value is long)
 | 
			
		||||
                    return "long";
 | 
			
		||||
                if (value is string)
 | 
			
		||||
                    return "string";
 | 
			
		||||
                if (value is bool)
 | 
			
		||||
                    return "boolean";
 | 
			
		||||
                if (value is decimal)
 | 
			
		||||
                    return "decimal";
 | 
			
		||||
                if (value is DateTime)
 | 
			
		||||
                    return "datetime";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string GetTypeName()
 | 
			
		||||
        {
 | 
			
		||||
            var value = GetRawObjectValue();
 | 
			
		||||
            return ResolveTypeName(value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public virtual void SetVariant(object raw)
 | 
			
		||||
        {
 | 
			
		||||
            ClearVariant();
 | 
			
		||||
            if (raw != null)
 | 
			
		||||
            {
 | 
			
		||||
                if (raw is int rawInt)
 | 
			
		||||
                    IntValue = rawInt;
 | 
			
		||||
                if (raw is long rawLong)
 | 
			
		||||
                    LongValue = rawLong;
 | 
			
		||||
                if (raw is string rawStr)
 | 
			
		||||
                    StringValue = rawStr;
 | 
			
		||||
                if (raw is bool rawBool)
 | 
			
		||||
                    BooleanValue = rawBool;
 | 
			
		||||
                if (raw is decimal rawDec)
 | 
			
		||||
                    DecimalValue = rawDec;
 | 
			
		||||
                if (raw is DateTime rawDt)
 | 
			
		||||
                    DateTimeValue = rawDt;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public virtual object GetRawObjectValue()
 | 
			
		||||
        {
 | 
			
		||||
            if (IntValue != null && IntValue is int)
 | 
			
		||||
                return IntValue;
 | 
			
		||||
            if (LongValue != null && LongValue is long)
 | 
			
		||||
                return LongValue;
 | 
			
		||||
            if (StringValue != null && StringValue is string)
 | 
			
		||||
                return StringValue;
 | 
			
		||||
            if (BooleanValue != null && BooleanValue is bool)
 | 
			
		||||
                return BooleanValue;
 | 
			
		||||
            if (DecimalValue != null && DecimalValue is decimal)
 | 
			
		||||
                return DecimalValue;
 | 
			
		||||
            if (DateTimeValue != null && DateTimeValue is DateTime)
 | 
			
		||||
                return DateTimeValue;
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int? IntValue { get; set; }
 | 
			
		||||
        public long? LongValue { get; set; }
 | 
			
		||||
        public string StringValue { get; set; }
 | 
			
		||||
        public decimal? DecimalValue { get; set; }
 | 
			
		||||
        public DateTime? DateTimeValue { get; set; }
 | 
			
		||||
        public bool? BooleanValue { get; set; }
 | 
			
		||||
 | 
			
		||||
        public virtual void ClearVariant()
 | 
			
		||||
        {
 | 
			
		||||
            this.IntValue = null;
 | 
			
		||||
            this.LongValue = null;
 | 
			
		||||
            this.StringValue = null;
 | 
			
		||||
            this.DecimalValue = null;
 | 
			
		||||
            this.DateTimeValue = null;
 | 
			
		||||
            this.BooleanValue = null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,8 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.DynamicQuery
 | 
			
		||||
{
 | 
			
		||||
    public class GraphQLVariantInput : GraphQLVariant
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,60 +0,0 @@
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.DynamicQuery
 | 
			
		||||
{
 | 
			
		||||
    public class GraphQLVariantResult : GraphQLVariant
 | 
			
		||||
    {
 | 
			
		||||
        public GraphQLVariantResult()
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public GraphQLVariantResult(object raw)
 | 
			
		||||
        {
 | 
			
		||||
            SetVariant(raw);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override string ResolveTypeName(object value)
 | 
			
		||||
        {
 | 
			
		||||
            var valueType = base.ResolveTypeName(value);
 | 
			
		||||
            if (value != null && valueType == null)
 | 
			
		||||
                return "json";
 | 
			
		||||
 | 
			
		||||
            return valueType;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override object GetRawObjectValue()
 | 
			
		||||
        {
 | 
			
		||||
            if (jsonValue != null)
 | 
			
		||||
                return jsonValue;
 | 
			
		||||
 | 
			
		||||
            return base.GetRawObjectValue();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private object jsonValue = null;
 | 
			
		||||
 | 
			
		||||
        public string Json
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                if (jsonValue != null)
 | 
			
		||||
                    return JsonConvert.SerializeObject(jsonValue, new JsonSerializerSettings
 | 
			
		||||
                    {
 | 
			
		||||
                        ReferenceLoopHandling = ReferenceLoopHandling.Ignore
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
            set
 | 
			
		||||
            {
 | 
			
		||||
                jsonValue = JsonConvert.DeserializeObject(value);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void ClearVariant()
 | 
			
		||||
        {
 | 
			
		||||
            base.ClearVariant();
 | 
			
		||||
            this.jsonValue = null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,21 +0,0 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <TargetFramework>netstandard2.0</TargetFramework>
 | 
			
		||||
    <Copyright>Powered Softwares Inc.</Copyright>
 | 
			
		||||
    <PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
 | 
			
		||||
    <Company>PoweredSoft</Company>
 | 
			
		||||
    <Authors>PoweredSoft Team</Authors>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
 | 
			
		||||
    <PackageReference Include="PoweredSoft.DynamicQuery" Version="3.0.1" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS.DynamicQuery.Abstractions\PoweredSoft.CQRS.DynamicQuery.Abstractions.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS.DynamicQuery\PoweredSoft.CQRS.DynamicQuery.csproj" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
@ -1,11 +0,0 @@
 | 
			
		||||
using PoweredSoft.CQRS.GraphQL.Abstractions;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.FluentValidation
 | 
			
		||||
{
 | 
			
		||||
    public class GraphQLFieldError : IGraphQLFieldError
 | 
			
		||||
    {
 | 
			
		||||
        public string Field { get; set; }
 | 
			
		||||
        public List<string> Errors { get; set; } = new List<string>();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,28 +0,0 @@
 | 
			
		||||
using FluentValidation.Results;
 | 
			
		||||
using PoweredSoft.CQRS.GraphQL.Abstractions;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.FluentValidation
 | 
			
		||||
{
 | 
			
		||||
    public class GraphQLFluentValidationResult : IGraphQLValidationResult
 | 
			
		||||
    {
 | 
			
		||||
        public bool IsValid => Errors.Count == 0;
 | 
			
		||||
        public List<IGraphQLFieldError> Errors { get; } = new List<IGraphQLFieldError>();
 | 
			
		||||
 | 
			
		||||
        public static GraphQLFluentValidationResult From(ValidationResult result)
 | 
			
		||||
        {
 | 
			
		||||
            var model = new GraphQLFluentValidationResult();
 | 
			
		||||
            foreach (var error in result.Errors)
 | 
			
		||||
            {
 | 
			
		||||
                var fieldError = new GraphQLFieldError
 | 
			
		||||
                {
 | 
			
		||||
                    Field = error.PropertyName
 | 
			
		||||
                };
 | 
			
		||||
                fieldError.Errors.Add(error.ErrorMessage);
 | 
			
		||||
                model.Errors.Add(fieldError);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return model;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,47 +0,0 @@
 | 
			
		||||
using FluentValidation;
 | 
			
		||||
using PoweredSoft.CQRS.GraphQL.Abstractions;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.FluentValidation
 | 
			
		||||
{
 | 
			
		||||
    public class GraphQLFluentValidationService : IGraphQLValidationService
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IServiceProvider serviceProvider;
 | 
			
		||||
 | 
			
		||||
        public GraphQLFluentValidationService(IServiceProvider serviceProvider)
 | 
			
		||||
        {
 | 
			
		||||
            this.serviceProvider = serviceProvider;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<IGraphQLValidationResult> ValidateAsync<T>(T subject, CancellationToken cancellationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            var validationService = serviceProvider.GetService(typeof(IValidator<T>)) as IValidator<T>;
 | 
			
		||||
            if (validationService == null)
 | 
			
		||||
                return new GraphQLValidResult();
 | 
			
		||||
 | 
			
		||||
            var result = await validationService.ValidateAsync(subject, cancellationToken);
 | 
			
		||||
            if (!result.IsValid)
 | 
			
		||||
                return GraphQLFluentValidationResult.From(result);
 | 
			
		||||
 | 
			
		||||
            return new GraphQLValidResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<IGraphQLValidationResult> ValidateObjectAsync(object subject, CancellationToken cancellationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            var validatorType = typeof(IValidator<>).MakeGenericType(subject.GetType());
 | 
			
		||||
            var validationService = serviceProvider.GetService(validatorType) as IValidator;
 | 
			
		||||
            if (validationService == null)
 | 
			
		||||
                return new GraphQLValidResult();
 | 
			
		||||
 | 
			
		||||
            var result = await validationService.ValidateAsync(new ValidationContext<object>(subject), cancellationToken);
 | 
			
		||||
            if (!result.IsValid)
 | 
			
		||||
                return GraphQLFluentValidationResult.From(result);
 | 
			
		||||
 | 
			
		||||
            return new GraphQLValidResult();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,11 +0,0 @@
 | 
			
		||||
using PoweredSoft.CQRS.GraphQL.Abstractions;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.FluentValidation
 | 
			
		||||
{
 | 
			
		||||
    public class GraphQLValidResult : IGraphQLValidationResult
 | 
			
		||||
    {
 | 
			
		||||
        public bool IsValid => true;
 | 
			
		||||
        public List<IGraphQLFieldError> Errors { get; } = new List<IGraphQLFieldError>();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,20 +0,0 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <TargetFramework>netstandard2.0</TargetFramework>
 | 
			
		||||
    <Copyright>Powered Softwares Inc.</Copyright>
 | 
			
		||||
    <PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
 | 
			
		||||
    <Company>PoweredSoft</Company>
 | 
			
		||||
    <Authors>PoweredSoft Team</Authors>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="FluentValidation" Version="10.3.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.0" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS.GraphQL.Abstractions\PoweredSoft.CQRS.GraphQL.Abstractions.csproj" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
@ -1,18 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection.Extensions;
 | 
			
		||||
using PoweredSoft.CQRS.GraphQL.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.FluentValidation
 | 
			
		||||
{
 | 
			
		||||
    public static class ServiceCollectionExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static IServiceCollection AddPoweredSoftGraphQLFluentValidation(this IServiceCollection services)
 | 
			
		||||
        {
 | 
			
		||||
            services.AddTransient<IGraphQLValidationService, GraphQLFluentValidationService>();
 | 
			
		||||
            return services;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,90 +0,0 @@
 | 
			
		||||
using HotChocolate.Types;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions.Discovery;
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery.Discover;
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.HotChocolate.DynamicQuery
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    internal class DynamicQueryObjectType : ObjectTypeExtension
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IQueryDiscovery queryDiscovery;
 | 
			
		||||
 | 
			
		||||
        public DynamicQueryObjectType(IQueryDiscovery queryDiscovery) : base()
 | 
			
		||||
        {
 | 
			
		||||
            this.queryDiscovery = queryDiscovery;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void Configure(IObjectTypeDescriptor descriptor)
 | 
			
		||||
        {
 | 
			
		||||
            base.Configure(descriptor);
 | 
			
		||||
            descriptor.Name("Query");
 | 
			
		||||
 | 
			
		||||
            foreach(var q in queryDiscovery.GetQueries())
 | 
			
		||||
            {
 | 
			
		||||
                if (q.Category == "DynamicQuery" && q is DynamicQueryMeta dq)
 | 
			
		||||
                {
 | 
			
		||||
                    var f = descriptor.Field(q.LowerCamelCaseName);
 | 
			
		||||
 | 
			
		||||
                    // service to execute with.
 | 
			
		||||
                    var queryHandlerServiceType = typeof(IQueryHandler<,>).MakeGenericType(dq.QueryType, dq.QueryResultType);
 | 
			
		||||
 | 
			
		||||
                    // destermine argument type.
 | 
			
		||||
                    Type argumentType;
 | 
			
		||||
                    Type runnerType;
 | 
			
		||||
                    if (dq.ParamsType != null)
 | 
			
		||||
                    {
 | 
			
		||||
                        argumentType = typeof(GraphQL.DynamicQuery.GraphQLDynamicQuery<,,>).MakeGenericType(
 | 
			
		||||
                            dq.SourceType, dq.DestinationType, dq.ParamsType);
 | 
			
		||||
 | 
			
		||||
                        runnerType = typeof(DynamicQueryRunnerWithParams<,,>)
 | 
			
		||||
                            .MakeGenericType(dq.SourceType, dq.DestinationType, dq.ParamsType);
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        argumentType = typeof(GraphQL.DynamicQuery.GraphQLDynamicQuery<,>).MakeGenericType(
 | 
			
		||||
                            dq.SourceType, dq.DestinationType);
 | 
			
		||||
 | 
			
		||||
                        runnerType = typeof(DynamicQueryRunner<,>)
 | 
			
		||||
                            .MakeGenericType(dq.SourceType, dq.DestinationType);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    f.Argument("params", a => a
 | 
			
		||||
                        .Type(argumentType)
 | 
			
		||||
                        .DefaultValue(Activator.CreateInstance(argumentType))
 | 
			
		||||
                        );
 | 
			
		||||
 | 
			
		||||
                    // make generic type of outgoing type.
 | 
			
		||||
                    var resultType = typeof(GraphQL.DynamicQuery.GraphQLDynamicQueryExecutionResult<>)
 | 
			
		||||
                        .MakeGenericType(dq.DestinationType);
 | 
			
		||||
 | 
			
		||||
                    f.Type(resultType);
 | 
			
		||||
 | 
			
		||||
                    // security middleware
 | 
			
		||||
                    f.Use((sp, d) => new QueryAuthorizationMiddleware(q.QueryType, d));
 | 
			
		||||
 | 
			
		||||
                    // middleware to validate.
 | 
			
		||||
                    f.Use<QueryValidationMiddleware>();
 | 
			
		||||
 | 
			
		||||
                    // resolver
 | 
			
		||||
                    f.Resolve(async r =>
 | 
			
		||||
                    {
 | 
			
		||||
                        dynamic argument = r.ArgumentValue<object>("params");
 | 
			
		||||
                       
 | 
			
		||||
                        // handler service.
 | 
			
		||||
                        var service = r.Service(queryHandlerServiceType);
 | 
			
		||||
 | 
			
		||||
                        // runner. 
 | 
			
		||||
                        dynamic runner = Activator.CreateInstance(runnerType, new object[] { service });
 | 
			
		||||
 | 
			
		||||
                        // get outcome.
 | 
			
		||||
                        object outcome = await runner.RunAsync(argument, r.RequestAborted);
 | 
			
		||||
 | 
			
		||||
                        return outcome;
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,28 +0,0 @@
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery;
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
 | 
			
		||||
using PoweredSoft.CQRS.GraphQL.DynamicQuery;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.HotChocolate.DynamicQuery
 | 
			
		||||
{
 | 
			
		||||
    public class DynamicQueryRunner<TSource, TDestination>
 | 
			
		||||
        where TSource : class
 | 
			
		||||
        where TDestination : class
 | 
			
		||||
    {
 | 
			
		||||
        private readonly DynamicQueryHandler<TSource, TDestination> handler;
 | 
			
		||||
 | 
			
		||||
        public DynamicQueryRunner(DynamicQueryHandler<TSource, TDestination> handler)
 | 
			
		||||
        {
 | 
			
		||||
            this.handler = handler;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<GraphQLDynamicQueryExecutionResult<TDestination>> RunAsync(IDynamicQuery<TSource, TDestination> query, CancellationToken cancellationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            var result = await handler.HandleAsync(query);
 | 
			
		||||
            var outcome = new GraphQLDynamicQueryExecutionResult<TDestination>();
 | 
			
		||||
            outcome.FromResult(result);
 | 
			
		||||
            return outcome;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,29 +0,0 @@
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery;
 | 
			
		||||
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
 | 
			
		||||
using PoweredSoft.CQRS.GraphQL.DynamicQuery;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.HotChocolate.DynamicQuery
 | 
			
		||||
{
 | 
			
		||||
    public class DynamicQueryRunnerWithParams<TSource, TDestination, TParams>
 | 
			
		||||
        where TSource : class
 | 
			
		||||
        where TDestination : class
 | 
			
		||||
        where TParams : class
 | 
			
		||||
    {
 | 
			
		||||
        private readonly DynamicQueryHandler<TSource, TDestination, TParams> handler;
 | 
			
		||||
 | 
			
		||||
        public DynamicQueryRunnerWithParams(DynamicQueryHandler<TSource, TDestination, TParams> handler)
 | 
			
		||||
        {
 | 
			
		||||
            this.handler = handler;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<GraphQLDynamicQueryExecutionResult<TDestination>> RunAsync(IDynamicQuery<TSource, TDestination, TParams> query, CancellationToken cancellationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            var result = await handler.HandleAsync(query);
 | 
			
		||||
            var outcome = new GraphQLDynamicQueryExecutionResult<TDestination>();
 | 
			
		||||
            outcome.FromResult(result);
 | 
			
		||||
            return outcome;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,21 +0,0 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <TargetFrameworks>netcoreapp3.1;net5.0</TargetFrameworks>
 | 
			
		||||
    <Copyright>Powered Softwares Inc.</Copyright>
 | 
			
		||||
    <PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
 | 
			
		||||
    <Company>PoweredSoft</Company>
 | 
			
		||||
    <Authors>PoweredSoft Team</Authors>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="HotChocolate" Version="11.3.4" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS.Abstractions\PoweredSoft.CQRS.Abstractions.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS.GraphQL.DynamicQuery\PoweredSoft.CQRS.GraphQL.DynamicQuery.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS.GraphQL.HotChocolate\PoweredSoft.CQRS.GraphQL.HotChocolate.csproj" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
@ -1,15 +0,0 @@
 | 
			
		||||
using HotChocolate.Execution.Configuration;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.HotChocolate.DynamicQuery
 | 
			
		||||
{
 | 
			
		||||
    public static class RequestExecutorBuilderExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static IRequestExecutorBuilder AddPoweredSoftDynamicQueries(this IRequestExecutorBuilder builder)
 | 
			
		||||
        {
 | 
			
		||||
            builder.AddTypeExtension<DynamicQueryObjectType>();
 | 
			
		||||
            return builder;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,46 +0,0 @@
 | 
			
		||||
using HotChocolate;
 | 
			
		||||
using HotChocolate.Resolvers;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions.Security;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.HotChocolate
 | 
			
		||||
{
 | 
			
		||||
    internal class MutationAuthorizationMiddleware
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Type mutationType;
 | 
			
		||||
        private readonly FieldDelegate _next;
 | 
			
		||||
 | 
			
		||||
        public MutationAuthorizationMiddleware(Type mutationType,FieldDelegate next)
 | 
			
		||||
        {
 | 
			
		||||
            this.mutationType = mutationType;
 | 
			
		||||
            _next = next;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task InvokeAsync(IMiddlewareContext context)
 | 
			
		||||
        {
 | 
			
		||||
            var mutationAuthorizationService = context.Service<IServiceProvider>().GetService<ICommandAuthorizationService>();
 | 
			
		||||
            if (mutationAuthorizationService != null)
 | 
			
		||||
            {
 | 
			
		||||
                var authorizationResult = await mutationAuthorizationService.IsAllowedAsync(mutationType);
 | 
			
		||||
                if (authorizationResult != AuthorizationResult.Allowed)
 | 
			
		||||
                {
 | 
			
		||||
                    var eb = ErrorBuilder.New()
 | 
			
		||||
                               .SetMessage(authorizationResult == AuthorizationResult.Unauthorized ? "Unauthorized" : "Forbidden")
 | 
			
		||||
                               .SetCode("AuthorizationResult")
 | 
			
		||||
                               .SetExtension("StatusCode", authorizationResult == AuthorizationResult.Unauthorized ? "401" : "403")
 | 
			
		||||
                               .SetPath(context.Path)
 | 
			
		||||
                               .AddLocation(context.Selection.SyntaxNode);
 | 
			
		||||
 | 
			
		||||
                    context.Result = eb.Build();
 | 
			
		||||
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            await _next.Invoke(context);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,79 +0,0 @@
 | 
			
		||||
using HotChocolate.Resolvers;
 | 
			
		||||
using HotChocolate.Types;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions.Discovery;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.HotChocolate
 | 
			
		||||
{
 | 
			
		||||
    public class MutationObjectType : ObjectTypeExtension
 | 
			
		||||
    {
 | 
			
		||||
        private readonly ICommandDiscovery commandDiscovery;
 | 
			
		||||
 | 
			
		||||
        public MutationObjectType(ICommandDiscovery commandDiscovery) : base()
 | 
			
		||||
        {
 | 
			
		||||
            this.commandDiscovery = commandDiscovery;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void Configure(IObjectTypeDescriptor desc)
 | 
			
		||||
        {
 | 
			
		||||
            desc.Name("Mutation");
 | 
			
		||||
            foreach (var m in commandDiscovery.GetCommands())
 | 
			
		||||
            {
 | 
			
		||||
                var mutationField = desc.Field(m.LowerCamelCaseName);
 | 
			
		||||
 | 
			
		||||
                Type typeToGet;
 | 
			
		||||
                if (m.CommandResultType == null)
 | 
			
		||||
                    typeToGet = typeof(ICommandHandler<>).MakeGenericType(m.CommandType);
 | 
			
		||||
                else
 | 
			
		||||
                    typeToGet = typeof(ICommandHandler<,>).MakeGenericType(m.CommandType, m.CommandResultType);
 | 
			
		||||
 | 
			
		||||
                if (m.CommandResultType == null)
 | 
			
		||||
                    mutationField.Type(typeof(int?));
 | 
			
		||||
                else
 | 
			
		||||
                    mutationField.Type(m.CommandResultType);
 | 
			
		||||
 | 
			
		||||
                //queryField.Use((sp, d) => new MutationAuthorizationMiddleware(m.CommandType, d));
 | 
			
		||||
 | 
			
		||||
                if (m.CommandType.GetProperties().Length == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    mutationField.Resolve(async ctx =>
 | 
			
		||||
                    {
 | 
			
		||||
                        var queryArgument = Activator.CreateInstance(m.CommandType);
 | 
			
		||||
                        return await HandleMutation(m.CommandResultType != null, ctx, typeToGet, queryArgument);
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                mutationField.Argument("params", t => t.Type(m.CommandType));
 | 
			
		||||
 | 
			
		||||
                mutationField.Resolve(async ctx =>
 | 
			
		||||
                {
 | 
			
		||||
                    var queryArgument = ctx.ArgumentValue<object>("params");
 | 
			
		||||
                    return await HandleMutation(m.CommandResultType != null, ctx, typeToGet, queryArgument);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                mutationField.Use<MutationParamRequiredMiddleware>();
 | 
			
		||||
                mutationField.Use<MutationValidationMiddleware>();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async System.Threading.Tasks.Task<object> HandleMutation(bool hasResult, IResolverContext ctx, Type typeToGet, object queryArgument)
 | 
			
		||||
        {
 | 
			
		||||
            dynamic service = ctx.Service(typeToGet);
 | 
			
		||||
 | 
			
		||||
            if (hasResult)
 | 
			
		||||
            {
 | 
			
		||||
                var result = await service.HandleAsync((dynamic)queryArgument);
 | 
			
		||||
                return result;
 | 
			
		||||
            } 
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                await service.HandleAsync((dynamic)queryArgument);
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,37 +0,0 @@
 | 
			
		||||
using HotChocolate;
 | 
			
		||||
using HotChocolate.Resolvers;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.HotChocolate
 | 
			
		||||
{
 | 
			
		||||
    public class MutationParamRequiredMiddleware
 | 
			
		||||
    {
 | 
			
		||||
        private readonly FieldDelegate _next;
 | 
			
		||||
 | 
			
		||||
        public MutationParamRequiredMiddleware(FieldDelegate next)
 | 
			
		||||
        {
 | 
			
		||||
            _next = next;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task InvokeAsync(IMiddlewareContext context)
 | 
			
		||||
        {
 | 
			
		||||
            var queryArgument = context.ArgumentValue<object>("params");
 | 
			
		||||
            if (queryArgument == null)
 | 
			
		||||
            {
 | 
			
		||||
                context.Result = ErrorBuilder.New()
 | 
			
		||||
                    .SetMessage("mutation argument is required")
 | 
			
		||||
                    .SetCode("400")
 | 
			
		||||
                    .SetPath(context.Path)
 | 
			
		||||
                    .AddLocation(context.Selection.SyntaxNode)
 | 
			
		||||
                    .Build();
 | 
			
		||||
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await _next.Invoke(context);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,47 +0,0 @@
 | 
			
		||||
using HotChocolate;
 | 
			
		||||
using HotChocolate.Resolvers;
 | 
			
		||||
using PoweredSoft.CQRS.GraphQL.Abstractions;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.HotChocolate
 | 
			
		||||
{
 | 
			
		||||
    public class MutationValidationMiddleware
 | 
			
		||||
    {
 | 
			
		||||
        private readonly FieldDelegate _next;
 | 
			
		||||
 | 
			
		||||
        public MutationValidationMiddleware(FieldDelegate next)
 | 
			
		||||
        {
 | 
			
		||||
            _next = next;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task InvokeAsync(IMiddlewareContext context)
 | 
			
		||||
        {
 | 
			
		||||
            var queryArgument = context.ArgumentValue<object>("params");
 | 
			
		||||
            if (queryArgument != null)
 | 
			
		||||
            {
 | 
			
		||||
                var service = context.Service<IGraphQLValidationService>();
 | 
			
		||||
                var result = await service.ValidateObjectAsync(queryArgument, context.RequestAborted);
 | 
			
		||||
                if (!result.IsValid)
 | 
			
		||||
                {
 | 
			
		||||
                    var eb = ErrorBuilder.New()
 | 
			
		||||
                               .SetMessage("There are some validations errors")
 | 
			
		||||
                               .SetCode("ValidationError")
 | 
			
		||||
                               .SetPath(context.Path)
 | 
			
		||||
                               .AddLocation(context.Selection.SyntaxNode);
 | 
			
		||||
 | 
			
		||||
                    foreach (var error in result.Errors)
 | 
			
		||||
                        eb.SetExtension(error.Field, error.Errors);
 | 
			
		||||
 | 
			
		||||
                    context.Result = eb.Build();
 | 
			
		||||
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await _next.Invoke(context);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,21 +0,0 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <TargetFrameworks>netcoreapp3.1;net5.0</TargetFrameworks>
 | 
			
		||||
    <Copyright>Powered Softwares Inc.</Copyright>
 | 
			
		||||
    <PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
 | 
			
		||||
    <Company>PoweredSoft</Company>
 | 
			
		||||
    <Authors>PoweredSoft Team</Authors>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="HotChocolate" Version="11.3.4" />
 | 
			
		||||
    <PackageReference Include="HotChocolate.Data" Version="11.3.4" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS.Abstractions\PoweredSoft.CQRS.Abstractions.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\PoweredSoft.CQRS.GraphQL.Abstractions\PoweredSoft.CQRS.GraphQL.Abstractions.csproj" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
@ -1,46 +0,0 @@
 | 
			
		||||
using HotChocolate;
 | 
			
		||||
using HotChocolate.Resolvers;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions.Security;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.HotChocolate
 | 
			
		||||
{
 | 
			
		||||
    public class QueryAuthorizationMiddleware
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Type queryType;
 | 
			
		||||
        private readonly FieldDelegate _next;
 | 
			
		||||
 | 
			
		||||
        public QueryAuthorizationMiddleware(Type queryType, FieldDelegate next)
 | 
			
		||||
        {
 | 
			
		||||
            this.queryType = queryType;
 | 
			
		||||
            _next = next;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task InvokeAsync(IMiddlewareContext context)
 | 
			
		||||
        {
 | 
			
		||||
            var queryAuthorizationService = context.Service<IServiceProvider>().GetService<IQueryAuthorizationService>();
 | 
			
		||||
            if (queryAuthorizationService != null)
 | 
			
		||||
            {
 | 
			
		||||
                var authorizationResult = await queryAuthorizationService.IsAllowedAsync(queryType);
 | 
			
		||||
                if (authorizationResult != AuthorizationResult.Allowed)
 | 
			
		||||
                {
 | 
			
		||||
                    var eb = ErrorBuilder.New()
 | 
			
		||||
                               .SetMessage(authorizationResult == AuthorizationResult.Unauthorized ? "Unauthorized" : "Forbidden")
 | 
			
		||||
                               .SetCode("AuthorizationResult")
 | 
			
		||||
                               .SetExtension("StatusCode", authorizationResult == AuthorizationResult.Unauthorized ? "401" : "403")
 | 
			
		||||
                               .SetPath(context.Path)
 | 
			
		||||
                               .AddLocation(context.Selection.SyntaxNode);
 | 
			
		||||
 | 
			
		||||
                    context.Result = eb.Build();
 | 
			
		||||
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            await _next.Invoke(context);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,89 +0,0 @@
 | 
			
		||||
using HotChocolate.Language;
 | 
			
		||||
using HotChocolate.Resolvers;
 | 
			
		||||
using HotChocolate.Types;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions;
 | 
			
		||||
using PoweredSoft.CQRS.Abstractions.Discovery;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.HotChocolate
 | 
			
		||||
{
 | 
			
		||||
    public class QueryObjectType : ObjectTypeExtension
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IQueryDiscovery queryDiscovery;
 | 
			
		||||
 | 
			
		||||
        public QueryObjectType(IQueryDiscovery queryDiscovery) : base()
 | 
			
		||||
        {
 | 
			
		||||
            this.queryDiscovery = queryDiscovery;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void Configure(IObjectTypeDescriptor desc)
 | 
			
		||||
        {
 | 
			
		||||
            desc.Name("Query");
 | 
			
		||||
            foreach (var q in queryDiscovery.GetQueries())
 | 
			
		||||
            {
 | 
			
		||||
                if (q.Category != "BasicQuery")
 | 
			
		||||
                    continue;
 | 
			
		||||
 | 
			
		||||
                var queryField = desc.Field(q.LowerCamelCaseName);
 | 
			
		||||
                var typeToGet = typeof(IQueryHandler<,>).MakeGenericType(q.QueryType, q.QueryResultType);
 | 
			
		||||
 | 
			
		||||
                queryField.Use((sp, d) => new QueryAuthorizationMiddleware(q.QueryType, d));
 | 
			
		||||
 | 
			
		||||
                // if its a IQueryable.
 | 
			
		||||
                if (q.QueryResultType.Namespace == "System.Linq" && q.QueryResultType.Name.Contains("IQueryable"))
 | 
			
		||||
                {
 | 
			
		||||
                    //waiting on answer to be determined.
 | 
			
		||||
                    //this does not work
 | 
			
		||||
                    //var genericArgument = q.QueryResultType.GetGenericArguments().First();
 | 
			
		||||
                    //var objectTypeOfAargument = typeof(ObjectType<>).MakeGenericType(genericArgument);
 | 
			
		||||
                    //var listType = typeof(ListType<>).MakeGenericType(objectTypeOfAargument);
 | 
			
		||||
                    //queryField.Type(objectTypeOfAargument);
 | 
			
		||||
                    //queryField.UseSingleOrDefault();
 | 
			
		||||
                    //queryField.UseProjection();
 | 
			
		||||
                    ////queryField.UsePaging(listType);
 | 
			
		||||
                    queryField.Type(q.QueryResultType);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    queryField.Type(q.QueryResultType);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (q.QueryType.GetProperties().Length == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    queryField.Resolve(async ctx =>
 | 
			
		||||
                    {
 | 
			
		||||
                        var queryArgument = Activator.CreateInstance(q.QueryType);
 | 
			
		||||
                        return await HandleQuery(ctx, typeToGet, queryArgument);
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                queryField.Argument("params", t => t.Type(q.QueryType));
 | 
			
		||||
 | 
			
		||||
                queryField.Resolve(async ctx =>
 | 
			
		||||
                {
 | 
			
		||||
                    var queryArgument = ctx.ArgumentValue<object>("params");
 | 
			
		||||
                    return await HandleQuery(ctx, typeToGet, queryArgument);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
                if (q.QueryObjectRequired)
 | 
			
		||||
                    queryField.Use<QueryParamRequiredMiddleware>();*/
 | 
			
		||||
 | 
			
		||||
                queryField.Use<QueryValidationMiddleware>();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async System.Threading.Tasks.Task<object> HandleQuery(IResolverContext resolverContext, Type typeToGet, object queryArgument)
 | 
			
		||||
        {
 | 
			
		||||
            dynamic service = resolverContext.Service(typeToGet);
 | 
			
		||||
            var result = await service.HandleAsync((dynamic)queryArgument);
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,47 +0,0 @@
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using HotChocolate;
 | 
			
		||||
using HotChocolate.Resolvers;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using PoweredSoft.CQRS.GraphQL.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.HotChocolate
 | 
			
		||||
{
 | 
			
		||||
    public class QueryValidationMiddleware
 | 
			
		||||
    {
 | 
			
		||||
        private readonly FieldDelegate _next;
 | 
			
		||||
 | 
			
		||||
        public QueryValidationMiddleware(FieldDelegate next)
 | 
			
		||||
        {
 | 
			
		||||
            _next = next;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task InvokeAsync(IMiddlewareContext context)
 | 
			
		||||
        {
 | 
			
		||||
            var queryArgument = context.ArgumentValue<object>("params");
 | 
			
		||||
            if (queryArgument != null)
 | 
			
		||||
            {
 | 
			
		||||
                var service = context.Service<IGraphQLValidationService>();
 | 
			
		||||
                var result = await service.ValidateObjectAsync(queryArgument, context.RequestAborted);
 | 
			
		||||
                if (!result.IsValid)
 | 
			
		||||
                {
 | 
			
		||||
                    var eb = ErrorBuilder.New()
 | 
			
		||||
                               .SetMessage("There are some validations errors")
 | 
			
		||||
                               .SetCode("ValidationError")
 | 
			
		||||
                               .SetPath(context.Path)
 | 
			
		||||
                               .AddLocation(context.Selection.SyntaxNode);
 | 
			
		||||
 | 
			
		||||
                    foreach (var error in result.Errors)
 | 
			
		||||
                        eb.SetExtension(error.Field, error.Errors);
 | 
			
		||||
 | 
			
		||||
                    context.Result = eb.Build();
 | 
			
		||||
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await _next.Invoke(context);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,22 +0,0 @@
 | 
			
		||||
using HotChocolate;
 | 
			
		||||
using HotChocolate.Execution.Configuration;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace PoweredSoft.CQRS.GraphQL.HotChocolate
 | 
			
		||||
{
 | 
			
		||||
    public static class RequestExecutorBuilderExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static IRequestExecutorBuilder AddPoweredSoftQueries(this IRequestExecutorBuilder builder)
 | 
			
		||||
        {
 | 
			
		||||
            builder.AddTypeExtension<QueryObjectType>();
 | 
			
		||||
            return builder;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IRequestExecutorBuilder AddPoweredSoftMutations(this IRequestExecutorBuilder builder)
 | 
			
		||||
        {
 | 
			
		||||
            builder.AddTypeExtension<MutationObjectType>();
 | 
			
		||||
            return builder;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user