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;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.Abstractions.Attributes
|
namespace PoweredSoft.CQRS.Abstractions.Attributes
|
||||||
{
|
{
|
||||||
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
|
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
|
||||||
public class CommandNameAttribute : Attribute
|
public class CommandNameAttribute : Attribute
|
||||||
{
|
{
|
||||||
public CommandNameAttribute(string name)
|
public CommandNameAttribute(string name)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace PoweredSoft.CQRS.Abstractions.Attributes
|
namespace PoweredSoft.CQRS.Abstractions.Attributes
|
||||||
{
|
{
|
||||||
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
|
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
|
||||||
public class QueryNameAttribute : Attribute
|
public class QueryNameAttribute : Attribute
|
||||||
{
|
{
|
||||||
public QueryNameAttribute(string name)
|
public QueryNameAttribute(string name)
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.Abstractions.Discovery
|
namespace PoweredSoft.CQRS.Abstractions.Discovery
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.Abstractions.Discovery
|
namespace PoweredSoft.CQRS.Abstractions.Discovery
|
||||||
{
|
{
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
using System;
|
using System.Threading;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.Abstractions
|
namespace PoweredSoft.CQRS.Abstractions
|
||||||
{
|
{
|
||||||
public interface ICommandHandler<TCommand>
|
public interface ICommandHandler<in TCommand>
|
||||||
where TCommand : class
|
where TCommand : class
|
||||||
{
|
{
|
||||||
Task HandleAsync(TCommand command, CancellationToken cancellationToken = default);
|
Task HandleAsync(TCommand command, CancellationToken cancellationToken = default);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ICommandHandler<TCommand, TCommandResult>
|
public interface ICommandHandler<in TCommand, TCommandResult>
|
||||||
where TCommand : class
|
where TCommand : class
|
||||||
{
|
{
|
||||||
Task<TCommandResult> HandleAsync(TCommand command, CancellationToken cancellationToken = default);
|
Task<TCommandResult> HandleAsync(TCommand command, CancellationToken cancellationToken = default);
|
||||||
|
@ -3,7 +3,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace PoweredSoft.CQRS.Abstractions
|
namespace PoweredSoft.CQRS.Abstractions
|
||||||
{
|
{
|
||||||
public interface IQueryHandler<TQuery, TQueryResult>
|
public interface IQueryHandler<in TQuery, TQueryResult>
|
||||||
where TQuery : class
|
where TQuery : class
|
||||||
{
|
{
|
||||||
Task<TQueryResult> HandleAsync(TQuery query, CancellationToken cancellationToken = default);
|
Task<TQueryResult> HandleAsync(TQuery query, CancellationToken cancellationToken = default);
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<Copyright>Powered Softwares Inc.</Copyright>
|
<Copyright>Powered Softwares Inc.</Copyright>
|
||||||
<PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
|
<PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
|
||||||
<Company>PoweredSoft</Company>
|
<Company>PoweredSoft</Company>
|
||||||
<Authors>PoweredSoft Team</Authors>
|
<Authors>PoweredSoft Team</Authors>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<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>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using PoweredSoft.CQRS.Abstractions.Discovery;
|
using PoweredSoft.CQRS.Abstractions.Discovery;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.Abstractions
|
namespace PoweredSoft.CQRS.Abstractions
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace PoweredSoft.CQRS.AspNetCore.Abstractions.Attributes
|
namespace PoweredSoft.CQRS.AspNetCore.Abstractions.Attributes
|
||||||
{
|
{
|
||||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
|
||||||
public class CommandControllerIgnoreAttribute : Attribute
|
public class CommandControllerIgnoreAttribute : Attribute
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.AspNetCore.Abstractions.Attributes
|
namespace PoweredSoft.CQRS.AspNetCore.Abstractions.Attributes
|
||||||
{
|
{
|
||||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
|
||||||
public class QueryControllerIgnoreAttribute : Attribute
|
public class QueryControllerIgnoreAttribute : Attribute
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<Copyright>Powered Softwares Inc.</Copyright>
|
<Copyright>Powered Softwares Inc.</Copyright>
|
||||||
<PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
|
<PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
|
||||||
<Company>PoweredSoft</Company>
|
<Company>PoweredSoft</Company>
|
||||||
<Authors>PoweredSoft Team</Authors>
|
<Authors>PoweredSoft Team</Authors>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using PoweredSoft.CQRS.Abstractions;
|
using PoweredSoft.CQRS.Abstractions;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.AspNetCore.Mvc
|
namespace PoweredSoft.CQRS.AspNetCore.Mvc
|
||||||
{
|
{
|
||||||
|
@ -11,16 +11,16 @@ namespace PoweredSoft.CQRS.AspNetCore.Mvc
|
|||||||
{
|
{
|
||||||
public class CommandControllerAsyncAuthorizationFilter : IAsyncAuthorizationFilter
|
public class CommandControllerAsyncAuthorizationFilter : IAsyncAuthorizationFilter
|
||||||
{
|
{
|
||||||
private readonly ICommandAuthorizationService _authorizationService;
|
private readonly ICommandAuthorizationService authorizationService;
|
||||||
|
|
||||||
public CommandControllerAsyncAuthorizationFilter(IServiceProvider serviceProvider)
|
public CommandControllerAsyncAuthorizationFilter(IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
_authorizationService = serviceProvider.GetService<ICommandAuthorizationService>();
|
authorizationService = serviceProvider.GetService<ICommandAuthorizationService>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
|
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
|
||||||
{
|
{
|
||||||
if (_authorizationService == null)
|
if (authorizationService == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var action = context.ActionDescriptor as Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor;
|
var action = context.ActionDescriptor as Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor;
|
||||||
@ -34,7 +34,7 @@ namespace PoweredSoft.CQRS.AspNetCore.Mvc
|
|||||||
else
|
else
|
||||||
commandType = action.ControllerTypeInfo.GenericTypeArguments.First();
|
commandType = action.ControllerTypeInfo.GenericTypeArguments.First();
|
||||||
|
|
||||||
var ar = await _authorizationService.IsAllowedAsync(commandType);
|
var ar = await authorizationService.IsAllowedAsync(commandType);
|
||||||
if (ar == AuthorizationResult.Forbidden)
|
if (ar == AuthorizationResult.Forbidden)
|
||||||
context.Result = new StatusCodeResult(403);
|
context.Result = new StatusCodeResult(403);
|
||||||
else if(ar == AuthorizationResult.Unauthorized)
|
else if(ar == AuthorizationResult.Unauthorized)
|
||||||
|
@ -16,13 +16,19 @@ namespace PoweredSoft.CQRS.AspNetCore.Mvc
|
|||||||
|
|
||||||
public void Apply(ControllerModel controller)
|
public void Apply(ControllerModel controller)
|
||||||
{
|
{
|
||||||
if (controller.ControllerType.IsGenericType && controller.ControllerType.Name.Contains("CommandController") && controller.ControllerType.Assembly == typeof(CommandControllerConvention).Assembly)
|
if (!controller.ControllerType.IsGenericType)
|
||||||
{
|
return;
|
||||||
var genericType = controller.ControllerType.GenericTypeArguments[0];
|
|
||||||
var commandDiscovery = this.serviceProvider.GetRequiredService<ICommandDiscovery>();
|
if (!controller.ControllerType.Name.Contains("CommandController"))
|
||||||
var command = commandDiscovery.FindCommand(genericType);
|
return;
|
||||||
controller.ControllerName = command.LowerCamelCaseName;
|
|
||||||
}
|
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.AspNetCore.Mvc.Controllers;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using PoweredSoft.CQRS.Abstractions.Discovery;
|
using PoweredSoft.CQRS.Abstractions.Discovery;
|
||||||
using PoweredSoft.CQRS.AspNetCore.Abstractions.Attributes;
|
using PoweredSoft.CQRS.AspNetCore.Abstractions.Attributes;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.AspNetCore.Mvc
|
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 PoweredSoft.CQRS.Abstractions;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.AspNetCore.Mvc
|
namespace PoweredSoft.CQRS.AspNetCore.Mvc
|
||||||
{
|
{
|
||||||
|
@ -11,16 +11,16 @@ namespace PoweredSoft.CQRS.AspNetCore.Mvc
|
|||||||
{
|
{
|
||||||
public class QueryControllerAsyncAuthorizationFilter : IAsyncAuthorizationFilter
|
public class QueryControllerAsyncAuthorizationFilter : IAsyncAuthorizationFilter
|
||||||
{
|
{
|
||||||
private readonly IQueryAuthorizationService _authorizationService;
|
private readonly IQueryAuthorizationService authorizationService;
|
||||||
|
|
||||||
public QueryControllerAsyncAuthorizationFilter(IServiceProvider serviceProvider)
|
public QueryControllerAsyncAuthorizationFilter(IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
_authorizationService = serviceProvider.GetService<IQueryAuthorizationService>();
|
authorizationService = serviceProvider.GetService<IQueryAuthorizationService>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
|
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
|
||||||
{
|
{
|
||||||
if (_authorizationService == null)
|
if (authorizationService == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var action = context.ActionDescriptor as Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor;
|
var action = context.ActionDescriptor as Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor;
|
||||||
@ -34,7 +34,7 @@ namespace PoweredSoft.CQRS.AspNetCore.Mvc
|
|||||||
else
|
else
|
||||||
queryType = action.ControllerTypeInfo.GenericTypeArguments.First();
|
queryType = action.ControllerTypeInfo.GenericTypeArguments.First();
|
||||||
|
|
||||||
var ar = await _authorizationService.IsAllowedAsync(queryType);
|
var ar = await authorizationService.IsAllowedAsync(queryType);
|
||||||
if (ar == AuthorizationResult.Forbidden)
|
if (ar == AuthorizationResult.Forbidden)
|
||||||
context.Result = new StatusCodeResult(403);
|
context.Result = new StatusCodeResult(403);
|
||||||
else if (ar == AuthorizationResult.Unauthorized)
|
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.AspNetCore.Mvc.Controllers;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using PoweredSoft.CQRS.Abstractions.Discovery;
|
using PoweredSoft.CQRS.Abstractions.Discovery;
|
||||||
using PoweredSoft.CQRS.AspNetCore.Abstractions.Attributes;
|
using PoweredSoft.CQRS.AspNetCore.Abstractions.Attributes;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.AspNetCore.Mvc
|
namespace PoweredSoft.CQRS.AspNetCore.Mvc
|
||||||
{
|
{
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
using System;
|
namespace PoweredSoft.CQRS.AspNetCore.Mvc
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.AspNetCore.Mvc
|
|
||||||
{
|
{
|
||||||
public class QueryControllerOptions
|
public class QueryControllerOptions
|
||||||
{
|
{
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>netcoreapp3.1;net5.0</TargetFrameworks>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<Copyright>Powered Softwares Inc.</Copyright>
|
<Copyright>Powered Softwares Inc.</Copyright>
|
||||||
<PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
|
<PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
|
||||||
<Company>PoweredSoft</Company>
|
<Company>PoweredSoft</Company>
|
||||||
<Authors>PoweredSoft Team</Authors>
|
<Authors>PoweredSoft Team</Authors>
|
||||||
|
<IsAotCompatible>true</IsAotCompatible>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
using System;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
using PoweredSoft.DynamicQuery.Core;
|
using System.Collections.Generic;
|
||||||
using System;
|
using PoweredSoft.DynamicQuery.Core;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.DynamicQuery.Abstractions
|
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 TSource : class
|
||||||
where TDestination : class
|
where TDestination : class
|
||||||
where TParams : class
|
where TParams : class
|
||||||
@ -21,7 +19,6 @@ namespace PoweredSoft.CQRS.DynamicQuery.Abstractions
|
|||||||
}
|
}
|
||||||
|
|
||||||
public interface IDynamicQuery
|
public interface IDynamicQuery
|
||||||
|
|
||||||
{
|
{
|
||||||
List<IFilter> GetFilters();
|
List<IFilter> GetFilters();
|
||||||
List<IGroup> GetGroups();
|
List<IGroup> GetGroups();
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
using PoweredSoft.DynamicQuery.Core;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.DynamicQuery.Abstractions
|
namespace PoweredSoft.CQRS.DynamicQuery.Abstractions
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
namespace PoweredSoft.CQRS.DynamicQuery.Abstractions
|
namespace PoweredSoft.CQRS.DynamicQuery.Abstractions
|
||||||
{
|
{
|
||||||
public interface IDynamicQueryParams<TParams>
|
public interface IDynamicQueryParams<out TParams>
|
||||||
where TParams : class
|
where TParams : class
|
||||||
{
|
{
|
||||||
TParams GetParams();
|
TParams GetParams();
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
using System;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@ -9,6 +6,6 @@ namespace PoweredSoft.CQRS.DynamicQuery.Abstractions
|
|||||||
{
|
{
|
||||||
public interface IQueryableProvider<TSource>
|
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">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<Copyright>Powered Softwares Inc.</Copyright>
|
<Copyright>Powered Softwares Inc.</Copyright>
|
||||||
<PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
|
<PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
|
||||||
<Company>PoweredSoft</Company>
|
<Company>PoweredSoft</Company>
|
||||||
@ -11,5 +10,4 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="PoweredSoft.DynamicQuery.Core" Version="3.0.1" />
|
<PackageReference Include="PoweredSoft.DynamicQuery.Core" Version="3.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</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;
|
||||||
using PoweredSoft.DynamicQuery.Core;
|
using PoweredSoft.DynamicQuery.Core;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore
|
namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore
|
||||||
{
|
{
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using System;
|
||||||
using PoweredSoft.DynamicQuery;
|
|
||||||
using PoweredSoft.DynamicQuery.Core;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using PoweredSoft.DynamicQuery;
|
||||||
|
using PoweredSoft.DynamicQuery.Core;
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore
|
namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore
|
||||||
{
|
{
|
||||||
@ -49,18 +49,29 @@ namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore
|
|||||||
object value = Value;
|
object value = Value;
|
||||||
if (Value is JsonElement jsonElement)
|
if (Value is JsonElement jsonElement)
|
||||||
{
|
{
|
||||||
if (jsonElement.ValueKind == JsonValueKind.String)
|
switch (jsonElement.ValueKind)
|
||||||
value = jsonElement.ToString();
|
{
|
||||||
else if (jsonElement.ValueKind == JsonValueKind.Number && jsonElement.TryGetInt64(out var l))
|
case JsonValueKind.String:
|
||||||
value = l;
|
value = jsonElement.ToString();
|
||||||
else if (jsonElement.ValueKind == JsonValueKind.True)
|
break;
|
||||||
value = true;
|
case JsonValueKind.Number:
|
||||||
else if (jsonElement.ValueKind == JsonValueKind.False)
|
if (jsonElement.ToString().Contains('.'))
|
||||||
value = false;
|
value = jsonElement.GetDecimal();
|
||||||
else if (jsonElement.ValueKind == JsonValueKind.Array)
|
else if (jsonElement.TryGetInt64(out var convertedValue))
|
||||||
throw new System.Exception("TODO");
|
value = convertedValue;
|
||||||
else
|
break;
|
||||||
value = null;
|
case JsonValueKind.True:
|
||||||
|
value = true;
|
||||||
|
break;
|
||||||
|
case JsonValueKind.False:
|
||||||
|
value = false;
|
||||||
|
break;
|
||||||
|
// TODO: Array support
|
||||||
|
default:
|
||||||
|
value = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var simpleFilter = new SimpleFilter
|
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.AspNetCore.Mvc;
|
||||||
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
|
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
|
||||||
using PoweredSoft.DynamicQuery.Core;
|
using PoweredSoft.DynamicQuery.Core;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
|
namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
|
||||||
{
|
{
|
||||||
[ApiController, Route("api/query/[controller]")]
|
[ApiController, Route("api/query/[controller]")]
|
||||||
public class DynamicQueryController<TUnderlyingQuery, TSource, TDestination> : Controller
|
public class DynamicQueryController<TSource, TDestination> : Controller
|
||||||
where TSource : class
|
where TSource : class
|
||||||
where TDestination : class
|
where TDestination : class
|
||||||
{
|
{
|
||||||
[HttpPost, QueryControllerAuthorization]
|
[HttpPost, QueryControllerAuthorization]
|
||||||
public async Task<IQueryExecutionResult<TDestination>> HandleAsync(
|
public async Task<IQueryExecutionResult<TDestination>> HandleAsync(
|
||||||
[FromBody] DynamicQuery<TSource, TDestination> query,
|
[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);
|
var result = await queryHandler.HandleAsync(query, HttpContext.RequestAborted);
|
||||||
@ -27,7 +25,7 @@ namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
|
|||||||
[HttpGet, QueryControllerAuthorization]
|
[HttpGet, QueryControllerAuthorization]
|
||||||
public async Task<IQueryExecutionResult<TDestination>> HandleGetAsync(
|
public async Task<IQueryExecutionResult<TDestination>> HandleGetAsync(
|
||||||
[FromQuery] DynamicQuery<TSource, TDestination> query,
|
[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);
|
var result = await queryHandler.HandleAsync(query, HttpContext.RequestAborted);
|
||||||
@ -36,7 +34,7 @@ namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
|
|||||||
}
|
}
|
||||||
|
|
||||||
[ApiController, Route("api/query/[controller]")]
|
[ApiController, Route("api/query/[controller]")]
|
||||||
public class DynamicQueryController<TUnderlyingQuery, TSource, TDestination, TParams> : Controller
|
public class DynamicQueryController<TSource, TDestination, TParams> : Controller
|
||||||
where TSource : class
|
where TSource : class
|
||||||
where TDestination : class
|
where TDestination : class
|
||||||
where TParams : class
|
where TParams : class
|
||||||
@ -44,7 +42,7 @@ namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
|
|||||||
[HttpPost, QueryControllerAuthorization]
|
[HttpPost, QueryControllerAuthorization]
|
||||||
public async Task<IQueryExecutionResult<TDestination>> HandleAsync(
|
public async Task<IQueryExecutionResult<TDestination>> HandleAsync(
|
||||||
[FromBody] DynamicQuery<TSource, TDestination, TParams> query,
|
[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);
|
var result = await queryHandler.HandleAsync(query, HttpContext.RequestAborted);
|
||||||
@ -54,7 +52,7 @@ namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
|
|||||||
[HttpGet, QueryControllerAuthorization]
|
[HttpGet, QueryControllerAuthorization]
|
||||||
public async Task<IQueryExecutionResult<TDestination>> HandleGetAsync(
|
public async Task<IQueryExecutionResult<TDestination>> HandleGetAsync(
|
||||||
[FromQuery] DynamicQuery<TSource, TDestination, TParams> query,
|
[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);
|
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 Microsoft.Extensions.DependencyInjection;
|
||||||
using PoweredSoft.CQRS.Abstractions.Discovery;
|
using PoweredSoft.CQRS.Abstractions.Discovery;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
|
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.AspNetCore.Mvc.Controllers;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using PoweredSoft.CQRS.Abstractions.Discovery;
|
using PoweredSoft.CQRS.Abstractions.Discovery;
|
||||||
using PoweredSoft.CQRS.AspNetCore.Abstractions.Attributes;
|
using PoweredSoft.CQRS.AspNetCore.Abstractions.Attributes;
|
||||||
using PoweredSoft.CQRS.DynamicQuery.Discover;
|
using PoweredSoft.CQRS.DynamicQuery.Discover;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
|
namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
|
||||||
{
|
{
|
||||||
@ -36,13 +34,13 @@ namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
|
|||||||
{
|
{
|
||||||
if (dynamicQueryMeta.ParamsType == null)
|
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();
|
var controllerTypeInfo = controllerType.GetTypeInfo();
|
||||||
feature.Controllers.Add(controllerTypeInfo);
|
feature.Controllers.Add(controllerTypeInfo);
|
||||||
}
|
}
|
||||||
else
|
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();
|
var controllerTypeInfo = controllerType.GetTypeInfo();
|
||||||
feature.Controllers.Add(controllerTypeInfo);
|
feature.Controllers.Add(controllerTypeInfo);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
using System;
|
namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc
|
|
||||||
{
|
{
|
||||||
public class DynamicQueryControllerOptions
|
public class DynamicQueryControllerOptions
|
||||||
{
|
{
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using System;
|
||||||
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using PoweredSoft.CQRS.DynamicQuery.AspNetCore.Mvc;
|
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
|
namespace PoweredSoft.CQRS.DynamicQuery.AspNetCore
|
||||||
{
|
{
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>netcoreapp3.1;net5.0</TargetFrameworks>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<Copyright>Powered Softwares Inc.</Copyright>
|
<Copyright>Powered Softwares Inc.</Copyright>
|
||||||
<PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
|
<PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
|
||||||
<Company>PoweredSoft</Company>
|
<Company>PoweredSoft</Company>
|
||||||
<Authors>PoweredSoft Team</Authors>
|
<Authors>PoweredSoft Team</Authors>
|
||||||
|
<IsAotCompatible>true</IsAotCompatible>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -19,5 +19,4 @@
|
|||||||
<ProjectReference Include="..\PoweredSoft.CQRS.DynamicQuery.Abstractions\PoweredSoft.CQRS.DynamicQuery.Abstractions.csproj" />
|
<ProjectReference Include="..\PoweredSoft.CQRS.DynamicQuery.Abstractions\PoweredSoft.CQRS.DynamicQuery.Abstractions.csproj" />
|
||||||
<ProjectReference Include="..\PoweredSoft.CQRS.DynamicQuery\PoweredSoft.CQRS.DynamicQuery.csproj" />
|
<ProjectReference Include="..\PoweredSoft.CQRS.DynamicQuery\PoweredSoft.CQRS.DynamicQuery.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
using PoweredSoft.CQRS.Abstractions.Discovery;
|
using System;
|
||||||
using PoweredSoft.CQRS.Discovery;
|
using Pluralize.NET;
|
||||||
using System;
|
using PoweredSoft.CQRS.Abstractions.Discovery;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.DynamicQuery.Discover
|
namespace PoweredSoft.CQRS.DynamicQuery.Discover
|
||||||
{
|
{
|
||||||
@ -23,7 +21,7 @@ namespace PoweredSoft.CQRS.DynamicQuery.Discover
|
|||||||
if (OverridableName != null)
|
if (OverridableName != null)
|
||||||
return OverridableName;
|
return OverridableName;
|
||||||
|
|
||||||
var pluralizer = new Pluralize.NET.Pluralizer();
|
var pluralizer = new Pluralizer();
|
||||||
return pluralizer.Pluralize(DestinationType.Name);
|
return pluralizer.Pluralize(DestinationType.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,8 +83,8 @@ namespace PoweredSoft.CQRS.DynamicQuery
|
|||||||
PageSize = query?.GetPageSize(),
|
PageSize = query?.GetPageSize(),
|
||||||
Filters = query?.GetFilters() ?? new List<IFilter>(),
|
Filters = query?.GetFilters() ?? new List<IFilter>(),
|
||||||
Sorts = query?.GetSorts() ?? new List<ISort>(),
|
Sorts = query?.GetSorts() ?? new List<ISort>(),
|
||||||
Groups = query.GetGroups() ?? new List<IGroup>(),
|
Groups = query?.GetGroups() ?? new List<IGroup>(),
|
||||||
Aggregates = query.GetAggregates() ?? new List<IAggregate>()
|
Aggregates = query?.GetAggregates() ?? new List<IAggregate>()
|
||||||
};
|
};
|
||||||
return criteria;
|
return criteria;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<Copyright>Powered Softwares Inc.</Copyright>
|
<Copyright>Powered Softwares Inc.</Copyright>
|
||||||
<PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
|
<PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
|
||||||
<Company>PoweredSoft</Company>
|
<Company>PoweredSoft</Company>
|
||||||
@ -17,5 +16,4 @@
|
|||||||
<ProjectReference Include="..\PoweredSoft.CQRS.DynamicQuery.Abstractions\PoweredSoft.CQRS.DynamicQuery.Abstractions.csproj" />
|
<ProjectReference Include="..\PoweredSoft.CQRS.DynamicQuery.Abstractions\PoweredSoft.CQRS.DynamicQuery.Abstractions.csproj" />
|
||||||
<ProjectReference Include="..\PoweredSoft.CQRS\PoweredSoft.CQRS.csproj" />
|
<ProjectReference Include="..\PoweredSoft.CQRS\PoweredSoft.CQRS.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -5,9 +5,6 @@ using PoweredSoft.CQRS.Abstractions.Discovery;
|
|||||||
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
|
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
|
||||||
using PoweredSoft.CQRS.DynamicQuery.Discover;
|
using PoweredSoft.CQRS.DynamicQuery.Discover;
|
||||||
using PoweredSoft.DynamicQuery.Core;
|
using PoweredSoft.DynamicQuery.Core;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace PoweredSoft.CQRS.DynamicQuery
|
namespace PoweredSoft.CQRS.DynamicQuery
|
||||||
{
|
{
|
||||||
@ -22,7 +19,7 @@ namespace PoweredSoft.CQRS.DynamicQuery
|
|||||||
where TDestination : class
|
where TDestination : class
|
||||||
{
|
{
|
||||||
// add query handler.
|
// 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.
|
// add for discovery purposes.
|
||||||
var queryType = typeof(IDynamicQuery<TSource, TDestination>);
|
var queryType = typeof(IDynamicQuery<TSource, TDestination>);
|
||||||
@ -68,7 +65,7 @@ namespace PoweredSoft.CQRS.DynamicQuery
|
|||||||
where TParams : class
|
where TParams : class
|
||||||
{
|
{
|
||||||
// add query handler.
|
// 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.
|
// add for discovery purposes.
|
||||||
var queryType = typeof(IDynamicQuery<TSource, TDestination, TParams>);
|
var queryType = typeof(IDynamicQuery<TSource, TDestination, TParams>);
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<Copyright>Powered Softwares Inc.</Copyright>
|
<Copyright>Powered Softwares Inc.</Copyright>
|
||||||
<PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
|
<PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;r=g&amp;d=retro</PackageIconUrl>
|
||||||
<Company>PoweredSoft</Company>
|
<Company>PoweredSoft</Company>
|
||||||
@ -9,11 +8,10 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="FluentValidation" Version="10.3.0" />
|
<PackageReference Include="FluentValidation" Version="10.4.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\PoweredSoft.CQRS\PoweredSoft.CQRS.csproj" />
|
<ProjectReference Include="..\PoweredSoft.CQRS\PoweredSoft.CQRS.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,12 +1,6 @@
|
|||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
||||||
using PoweredSoft.CQRS.Abstractions;
|
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
|
namespace PoweredSoft.CQRS.FluentValidation
|
||||||
{
|
{
|
||||||
@ -19,7 +13,7 @@ namespace PoweredSoft.CQRS.FluentValidation
|
|||||||
return services;
|
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 TCommand : class
|
||||||
where TCommandHandler : class, ICommandHandler<TCommand>
|
where TCommandHandler : class, ICommandHandler<TCommand>
|
||||||
where TValidator : class, IValidator<TCommand>
|
where TValidator : class, IValidator<TCommand>
|
||||||
@ -28,7 +22,7 @@ namespace PoweredSoft.CQRS.FluentValidation
|
|||||||
.AddFluentValidator<TCommand, TValidator>();
|
.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 TCommand : class
|
||||||
where TCommandHandler : class, ICommandHandler<TCommand, TCommandResult>
|
where TCommandHandler : class, ICommandHandler<TCommand, TCommandResult>
|
||||||
where TValidator : class, IValidator<TCommand>
|
where TValidator : class, IValidator<TCommand>
|
||||||
@ -37,7 +31,7 @@ namespace PoweredSoft.CQRS.FluentValidation
|
|||||||
.AddFluentValidator<TCommand, TValidator>();
|
.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 TQuery : class
|
||||||
where TQueryHandler : class, IQueryHandler<TQuery, TQueryResult>
|
where TQueryHandler : class, IQueryHandler<TQuery, TQueryResult>
|
||||||
where TValidator : class, IValidator<TQuery>
|
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