update namespaces

refactor the name of the organisation
This commit is contained in:
Mathias Beaulieu-Duncan
2023-11-04 15:24:56 -04:00
parent 88c86513e9
commit 1c81288895
116 changed files with 1695 additions and 1747 deletions
@@ -0,0 +1,38 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using OpenHarbor.CQRS.Abstractions;
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
[Produces("application/json")]
[ApiController, Route("api/command/[controller]")]
public class CommandController<TCommand> : Controller
where TCommand : class
{
[HttpPost, CommandControllerAuthorization]
public async Task<IActionResult> Handle([FromServices] ICommandHandler<TCommand> handler,
[FromBody] TCommand command)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
await handler.HandleAsync(command, this.Request.HttpContext.RequestAborted);
return Ok();
}
}
[Produces("application/json")]
[ApiController, Route("api/command/[controller]")]
public class CommandController<TCommand, TTCommandResult> : Controller
where TCommand : class
{
[HttpPost, CommandControllerAuthorization]
public async Task<ActionResult<TTCommandResult>> Handle([FromServices] ICommandHandler<TCommand, TTCommandResult> handler,
[FromBody] TCommand command)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
return Ok(await handler.HandleAsync(command, this.Request.HttpContext.RequestAborted));
}
}
@@ -0,0 +1,43 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using System.Reflection;
using OpenHarbor.CQRS.Abstractions.Security;
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
public class CommandControllerAsyncAuthorizationFilter : IAsyncAuthorizationFilter
{
private readonly ICommandAuthorizationService _authorizationService;
public CommandControllerAsyncAuthorizationFilter(IServiceProvider serviceProvider)
{
_authorizationService = serviceProvider.GetService<ICommandAuthorizationService>();
}
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
if (_authorizationService == null)
return;
var action = context.ActionDescriptor as Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor;
if (action == null)
throw new Exception("Only Supports controller action descriptor");
var attribute = action.MethodInfo.GetCustomAttribute<CommandControllerAuthorizationAttribute>();
Type commandType;
if (attribute?.CommandType != null)
commandType = attribute.CommandType;
else
commandType = action.ControllerTypeInfo.GenericTypeArguments.First();
var ar = await _authorizationService.IsAllowedAsync(commandType);
if (ar == AuthorizationResult.Forbidden)
context.Result = new StatusCodeResult(403);
else if(ar == AuthorizationResult.Unauthorized)
context.Result = new StatusCodeResult(401);
}
}
@@ -0,0 +1,20 @@
using System;
using Microsoft.AspNetCore.Mvc;
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
[AttributeUsage(AttributeTargets.Method)]
public class CommandControllerAuthorizationAttribute : TypeFilterAttribute
{
public CommandControllerAuthorizationAttribute() : base(typeof(CommandControllerAsyncAuthorizationFilter))
{
}
public CommandControllerAuthorizationAttribute(Type commandType) : base(typeof(CommandControllerAsyncAuthorizationFilter))
{
CommandType = commandType;
}
public Type CommandType { get; } = null;
}
@@ -0,0 +1,33 @@
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.Extensions.DependencyInjection;
using OpenHarbor.CQRS.Abstractions.Discovery;
using System;
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
public class CommandControllerConvention : IControllerModelConvention
{
private readonly IServiceProvider _serviceProvider;
public CommandControllerConvention(IServiceProvider serviceProvider)
{
this._serviceProvider = serviceProvider;
}
public void Apply(ControllerModel controller)
{
if (!controller.ControllerType.IsGenericType)
return;
if (!controller.ControllerType.Name.Contains("CommandController"))
return;
if (controller.ControllerType.Assembly != typeof(CommandControllerConvention).Assembly)
return;
var genericType = controller.ControllerType.GenericTypeArguments[0];
var commandDiscovery = this._serviceProvider.GetRequiredService<ICommandDiscovery>();
var command = commandDiscovery.FindCommand(genericType);
controller.ControllerName = command.LowerCamelCaseName;
}
}
@@ -0,0 +1,43 @@
using System.Collections.Generic;
using System.Reflection;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyInjection;
using OpenHarbor.CQRS.Abstractions.Discovery;
using OpenHarbor.CQRS.AspNetCore.Abstractions.Attributes;
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
public class CommandControllerFeatureProvider : IApplicationFeatureProvider<ControllerFeature>
{
private readonly ServiceProvider _serviceProvider;
public CommandControllerFeatureProvider(ServiceProvider serviceProvider)
{
this._serviceProvider = serviceProvider;
}
public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllerFeature feature)
{
var commandDiscovery = this._serviceProvider.GetRequiredService<ICommandDiscovery>();
foreach (var f in commandDiscovery.GetCommands())
{
var ignoreAttribute = f.CommandType.GetCustomAttribute<CommandControllerIgnoreAttribute>();
if (ignoreAttribute != null)
continue;
if (f.CommandResultType == null)
{
var controllerType = typeof(CommandController<>).MakeGenericType(f.CommandType);
var controllerTypeInfo = controllerType.GetTypeInfo();
feature.Controllers.Add(controllerTypeInfo);
}
else
{
var controllerType = typeof(CommandController<,>).MakeGenericType(f.CommandType, f.CommandResultType);
var controllerTypeInfo = controllerType.GetTypeInfo();
feature.Controllers.Add(controllerTypeInfo);
}
}
}
}
@@ -0,0 +1,6 @@
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
public class CommandControllerOptions
{
}
@@ -0,0 +1,27 @@
using System;
using Microsoft.Extensions.DependencyInjection;
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
public static class MvcBuilderExtensions
{
public static IMvcBuilder AddPoweredSoftQueries(this IMvcBuilder builder, Action<QueryControllerOptions> configuration = null)
{
var options = new QueryControllerOptions();
configuration?.Invoke(options);
var services = builder.Services;
var serviceProvider = services.BuildServiceProvider();
builder.AddMvcOptions(o => o.Conventions.Add(new QueryControllerConvention(serviceProvider)));
builder.ConfigureApplicationPartManager(m => m.FeatureProviders.Add(new QueryControllerFeatureProvider(serviceProvider)));
return builder;
}
public static IMvcBuilder AddPoweredSoftCommands(this IMvcBuilder builder)
{
var services = builder.Services;
var serviceProvider = services.BuildServiceProvider();
builder.AddMvcOptions(o => o.Conventions.Add(new CommandControllerConvention(serviceProvider)));
builder.ConfigureApplicationPartManager(m => m.FeatureProviders.Add(new CommandControllerFeatureProvider(serviceProvider)));
return builder;
}
}
@@ -0,0 +1,33 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using OpenHarbor.CQRS.Abstractions;
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
[Produces("application/json")]
[ApiController, Route("api/query/[controller]")]
public class QueryController<TQuery, TQueryResult> : Controller
where TQuery : class
{
[HttpPost, QueryControllerAuthorization]
public async Task<ActionResult<TQueryResult>> Handle([FromServices] IQueryHandler<TQuery, TQueryResult> handler,
[FromBody] TQuery query)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
return Ok(await handler.HandleAsync(query, this.Request.HttpContext.RequestAborted));
}
[HttpGet, QueryControllerAuthorization]
public async Task<ActionResult<TQueryResult>> HandleGet([FromServices] IQueryHandler<TQuery, TQueryResult> handler,
[FromQuery] TQuery query)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
return Ok(await handler.HandleAsync(query, this.Request.HttpContext.RequestAborted));
}
}
@@ -0,0 +1,43 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using System.Reflection;
using OpenHarbor.CQRS.Abstractions.Security;
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
public class QueryControllerAsyncAuthorizationFilter : IAsyncAuthorizationFilter
{
private readonly IQueryAuthorizationService _authorizationService;
public QueryControllerAsyncAuthorizationFilter(IServiceProvider serviceProvider)
{
_authorizationService = serviceProvider.GetService<IQueryAuthorizationService>();
}
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
if (_authorizationService == null)
return;
var action = context.ActionDescriptor as Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor;
if (action == null)
throw new Exception("Only Supports controller action descriptor");
var attribute = action.MethodInfo.GetCustomAttribute<QueryControllerAuthorizationAttribute>();
Type queryType;
if (attribute?.QueryType != null)
queryType = attribute.QueryType;
else
queryType = action.ControllerTypeInfo.GenericTypeArguments.First();
var ar = await _authorizationService.IsAllowedAsync(queryType);
if (ar == AuthorizationResult.Forbidden)
context.Result = new StatusCodeResult(403);
else if (ar == AuthorizationResult.Unauthorized)
context.Result = new StatusCodeResult(401);
}
}
@@ -0,0 +1,20 @@
using System;
using Microsoft.AspNetCore.Mvc;
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
[AttributeUsage(AttributeTargets.Method)]
public class QueryControllerAuthorizationAttribute : TypeFilterAttribute
{
public QueryControllerAuthorizationAttribute() : base(typeof(QueryControllerAsyncAuthorizationFilter))
{
}
public QueryControllerAuthorizationAttribute(Type queryType) : base(typeof(QueryControllerAsyncAuthorizationFilter))
{
QueryType = queryType;
}
public Type QueryType { get; }
}
@@ -0,0 +1,27 @@
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.Extensions.DependencyInjection;
using OpenHarbor.CQRS.Abstractions.Discovery;
using System;
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
public class QueryControllerConvention : IControllerModelConvention
{
private readonly IServiceProvider _serviceProvider;
public QueryControllerConvention(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public void Apply(ControllerModel controller)
{
if (controller.ControllerType.IsGenericType && controller.ControllerType.Name.Contains("QueryController") && controller.ControllerType.Assembly == typeof(QueryControllerConvention).Assembly)
{
var genericType = controller.ControllerType.GenericTypeArguments[0];
var queryDiscovery = _serviceProvider.GetRequiredService<IQueryDiscovery>();
var query = queryDiscovery.FindQuery(genericType);
controller.ControllerName = query.LowerCamelCaseName;
}
}
}
@@ -0,0 +1,37 @@
using System.Collections.Generic;
using System.Reflection;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyInjection;
using OpenHarbor.CQRS.Abstractions.Discovery;
using OpenHarbor.CQRS.AspNetCore.Abstractions.Attributes;
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
public class QueryControllerFeatureProvider : IApplicationFeatureProvider<ControllerFeature>
{
private readonly ServiceProvider _serviceProvider;
public QueryControllerFeatureProvider(ServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllerFeature feature)
{
var queryDiscovery = this._serviceProvider.GetRequiredService<IQueryDiscovery>();
foreach (var f in queryDiscovery.GetQueries())
{
var ignoreAttribute = f.QueryType.GetCustomAttribute<QueryControllerIgnoreAttribute>();
if (ignoreAttribute != null)
continue;
if (f.Category != "BasicQuery")
continue;
var controllerType = typeof(QueryController<,>).MakeGenericType(f.QueryType, f.QueryResultType);
var controllerTypeInfo = controllerType.GetTypeInfo();
feature.Controllers.Add(controllerTypeInfo);
}
}
}
@@ -0,0 +1,6 @@
namespace OpenHarbor.CQRS.AspNetCore.Mvc;
public class QueryControllerOptions
{
}
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<PackageIconUrl>https://avatars.githubusercontent.com/u/52874619?v=4</PackageIconUrl>
<Authors>David Lebee, Mathias Beaulieu-Duncan</Authors>
<IsAotCompatible>true</IsAotCompatible>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OpenHarbor.CQRS.Abstractions\OpenHarbor.CQRS.Abstractions.csproj" />
<ProjectReference Include="..\OpenHarbor.CQRS.AspNetCore.Abstractions\OpenHarbor.CQRS.AspNetCore.Abstractions.csproj" />
</ItemGroup>
</Project>