Skip to content

Commit

Permalink
ServerExecutionBase
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidEggenberger committed Mar 2, 2024
1 parent f35f2d7 commit 0bbb374
Show file tree
Hide file tree
Showing 16 changed files with 171 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public async Task<ActionResult> RedirectToStripePremiumSubscription([FromRoute]
TenantId = ExecutionContext.TenantId,
RedirectBaseUrl = ExecutionContext.BaseURI.AbsoluteUri
};
var checkoutSession = await commandDispatcher.DispatchAsync<CreateStripeCheckoutSession, Stripe.Checkout.Session>(createStripeCheckoutSession);
var checkoutSession = await CommandDispatcher.DispatchAsync<CreateStripeCheckoutSession, Stripe.Checkout.Session>(createStripeCheckoutSession);

Response.Headers.Add("Location", checkoutSession.Url);
return new StatusCodeResult(303);
Expand All @@ -41,7 +41,7 @@ public async Task<ActionResult> Create()
UserId = ExecutionContext.UserId,
RedirectBaseUrl = ExecutionContext.BaseURI.AbsoluteUri,
};
var billingPortalSession = await commandDispatcher.DispatchAsync<CreateStripeBillingPortalSession, Stripe.BillingPortal.Session>(createBillingPortalSession);
var billingPortalSession = await CommandDispatcher.DispatchAsync<CreateStripeBillingPortalSession, Stripe.BillingPortal.Session>(createBillingPortalSession);

Response.Headers.Add("Location", billingPortalSession.Url);
return new StatusCodeResult(303);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public TenantsController(SignInManager<ApplicationUser> signInManager, IServiceP
public async Task<ActionResult<TenantDTO>> GetTenant()
{
var tenantId = ExecutionContext.TenantId;
TenantDTO tenant = await ExecutionContext.QueryDispatcher.DispatchAsync<GetTenantByID, TenantDTO>(new GetTenantByID { TenantId = tenantId });
TenantDTO tenant = await QueryDispatcher.DispatchAsync<GetTenantByID, TenantDTO>(new GetTenantByID { TenantId = tenantId });

return Ok(tenant);
}
Expand All @@ -41,7 +41,7 @@ public async Task<ActionResult<TenantDTO>> GetTenant()
public async Task<ActionResult<TenantDetailDTO>> GetTenantDetail()
{
var tenantId = ExecutionContext.TenantId;
TenantDetailDTO tenantDetail = await queryDispatcher.DispatchAsync<GetTenantDetailsByID, TenantDetailDTO>(new GetTenantDetailsByID { TenantId = tenantId });
TenantDetailDTO tenantDetail = await QueryDispatcher.DispatchAsync<GetTenantDetailsByID, TenantDetailDTO>(new GetTenantDetailsByID { TenantId = tenantId });

return Ok(tenantDetail);
}
Expand All @@ -51,24 +51,24 @@ public async Task<ActionResult<TenantDetailDTO>> GetTenantDetail()
public async Task<ActionResult<IEnumerable<TenantDTO>>> GetAllTenantsWhereUserIsMember()
{
var userId = ExecutionContext.UserId;
List<TenantMembershipDTO> teamMemberships = await queryDispatcher.DispatchAsync<GetAllTenantMembershipsOfUser, List<TenantMembershipDTO>>(null);
List<TenantMembershipDTO> teamMemberships = await QueryDispatcher.DispatchAsync<GetAllTenantMembershipsOfUser, List<TenantMembershipDTO>>(null);

return Ok(teamMemberships);
}

[HttpPost]
public async Task<ActionResult<TenantDTO>> CreateTenant(CreateTenantDTO createTenantDTO)
{
validationService.ThrowIfInvalidModel(createTenantDTO);
ValidationService.ThrowIfInvalidModel(createTenantDTO);

var createTenant = new CreateTenantWithAdmin
{
AdminId = ExecutionContext.UserId,
Name = createTenantDTO.Name
};
var createdTenant = await commandDispatcher.DispatchAsync<CreateTenantWithAdmin, TenantDTO>(null);
var createdTenant = await CommandDispatcher.DispatchAsync<CreateTenantWithAdmin, TenantDTO>(null);

var user = await queryDispatcher.DispatchAsync<GetUserById, ApplicationUser>(new GetUserById { });
var user = await QueryDispatcher.DispatchAsync<GetUserById, ApplicationUser>(new GetUserById { });
await signInManager.RefreshSignInAsync(user);

return CreatedAtAction(nameof(CreateTenant), createdTenant);
Expand All @@ -77,10 +77,10 @@ public async Task<ActionResult<TenantDTO>> CreateTenant(CreateTenantDTO createTe
[HttpDelete("{id}")]
public async Task DeleteTenant(Guid id)
{
await commandDispatcher.DispatchAsync<DeleteTenant>(new DeleteTenant { });
await CommandDispatcher.DispatchAsync<DeleteTenant>(new DeleteTenant { });

var userId = ExecutionContext.UserId;
var user = await queryDispatcher.DispatchAsync<GetUserById, ApplicationUser>(new GetUserById { });
var user = await QueryDispatcher.DispatchAsync<GetUserById, ApplicationUser>(new GetUserById { });

await signInManager.RefreshSignInAsync(user);
}
Expand All @@ -90,23 +90,23 @@ public async Task<ActionResult> CreateTenantMembership(InviteUserToTenantDTO inv
{
var userId = ExecutionContext.UserId;

await commandDispatcher.DispatchAsync<AddUserToTenant>(null);
await CommandDispatcher.DispatchAsync<AddUserToTenant>(null);

return Ok();
}

[HttpPut("memberships")]
public async Task<ActionResult> UpdateTenantMembership(ChangeRoleOfTenantMemberDTO changeRoleOfTeamMemberDTO)
{
await commandDispatcher.DispatchAsync<UpdateTenantMembership>(new UpdateTenantMembership { });
await CommandDispatcher.DispatchAsync<UpdateTenantMembership>(new UpdateTenantMembership { });

return Ok();
}

[HttpDelete("memberships/{userId}")]
public async Task<ActionResult> DeleteTenantMembership(Guid id)
{
await commandDispatcher.DispatchAsync<RemoveUserFromTenant>(new RemoveUserFromTenant { });
await CommandDispatcher.DispatchAsync<RemoveUserFromTenant>(new RemoveUserFromTenant { });

return Ok();
}
Expand Down
30 changes: 30 additions & 0 deletions Source/Shared/Features/CQRS/Command/BaseCommandHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Microsoft.Extensions.DependencyInjection;
using Shared.Features.CQRS.DomainEvent;
using Shared.Features.CQRS.IntegrationEvent;
using Shared.Features.CQRS.Query;
using Shared.Kernel.BuildingBlocks.ModelValidation;
using Shared.Kernel.BuildingBlocks;
using Shared.Features.Server;

namespace Shared.Features.CQRS.Command
{
public class BaseCommandHandler : ServerExecutionBase
{
public IExecutionContext ExecutionContext { get; }
public ICommandDispatcher CommandDispatcher { get; }
public IQueryDispatcher QueryDispatcher { get; }
public IIntegrationEventDispatcher IntegrationEventDispatcher { get; }
public IDomainEventDispatcher DomainEventDispatcher { get; }
public IValidationService ValidationService { get; }

public BaseCommandHandler(IServiceProvider serviceProvider)
{
ExecutionContext = serviceProvider.GetRequiredService<IExecutionContext>();
CommandDispatcher = serviceProvider.GetRequiredService<ICommandDispatcher>();
QueryDispatcher = serviceProvider.GetRequiredService<IQueryDispatcher>();
IntegrationEventDispatcher = serviceProvider.GetRequiredService<IIntegrationEventDispatcher>();
DomainEventDispatcher = serviceProvider.GetRequiredService<IDomainEventDispatcher>();
ValidationService = serviceProvider.GetRequiredService<IValidationService>();
}
}
}
4 changes: 2 additions & 2 deletions Source/Shared/Features/CQRS/Command/ICommandHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

namespace Shared.Features.CQRS.Command
{
public interface ICommandHandler<in TCommand> : IInServerExecutionScope where TCommand : ICommand
public interface ICommandHandler<in TCommand> : ServerExecutionBase where TCommand : ICommand

Check failure on line 5 in Source/Shared/Features/CQRS/Command/ICommandHandler.cs

View workflow job for this annotation

GitHub Actions / build

Type 'ServerExecutionBase' in interface list is not an interface

Check failure on line 5 in Source/Shared/Features/CQRS/Command/ICommandHandler.cs

View workflow job for this annotation

GitHub Actions / build

Type 'ServerExecutionBase' in interface list is not an interface
{
Task HandleAsync(TCommand command, CancellationToken cancellationToken);
}
public interface ICommandHandler<in TCommand, TResult> : IInServerExecutionScope where TCommand : ICommand<TResult>
public interface ICommandHandler<in TCommand, TResult> : ServerExecutionBase where TCommand : ICommand<TResult>

Check failure on line 9 in Source/Shared/Features/CQRS/Command/ICommandHandler.cs

View workflow job for this annotation

GitHub Actions / build

Type 'ServerExecutionBase' in interface list is not an interface

Check failure on line 9 in Source/Shared/Features/CQRS/Command/ICommandHandler.cs

View workflow job for this annotation

GitHub Actions / build

Type 'ServerExecutionBase' in interface list is not an interface
{
Task<TResult> HandleAsync(TCommand command, CancellationToken cancellationToken);
}
Expand Down
30 changes: 30 additions & 0 deletions Source/Shared/Features/CQRS/DomainEvent/BaseDomainEventHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Microsoft.Extensions.DependencyInjection;
using Shared.Features.CQRS.Command;
using Shared.Features.CQRS.IntegrationEvent;
using Shared.Features.CQRS.Query;
using Shared.Kernel.BuildingBlocks.ModelValidation;
using Shared.Kernel.BuildingBlocks;
using Shared.Features.Server;

namespace Shared.Features.CQRS.DomainEvent
{
public class BaseDomainEventHandler : ServerExecutionBase
{
public IExecutionContext ExecutionContext { get; }
public ICommandDispatcher CommandDispatcher { get; }
public IQueryDispatcher QueryDispatcher { get; }
public IIntegrationEventDispatcher IntegrationEventDispatcher { get; }
public IDomainEventDispatcher DomainEventDispatcher { get; }
public IValidationService ValidationService { get; }

public BaseDomainEventHandler(IServiceProvider serviceProvider)
{
ExecutionContext = serviceProvider.GetRequiredService<IExecutionContext>();
CommandDispatcher = serviceProvider.GetRequiredService<ICommandDispatcher>();
QueryDispatcher = serviceProvider.GetRequiredService<IQueryDispatcher>();
IntegrationEventDispatcher = serviceProvider.GetRequiredService<IIntegrationEventDispatcher>();
DomainEventDispatcher = serviceProvider.GetRequiredService<IDomainEventDispatcher>();
ValidationService = serviceProvider.GetRequiredService<IValidationService>();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Shared.Features.CQRS.DomainEvent
{
public interface IDomainEventHandler<in TDomainEvent> : IInServerExecutionScope where TDomainEvent : IDomainEvent
public interface IDomainEventHandler<in TDomainEvent> : ServerExecutionBase where TDomainEvent : IDomainEvent

Check failure on line 6 in Source/Shared/Features/CQRS/DomainEvent/IDomainEventHandler.cs

View workflow job for this annotation

GitHub Actions / build

Type 'ServerExecutionBase' in interface list is not an interface

Check failure on line 6 in Source/Shared/Features/CQRS/DomainEvent/IDomainEventHandler.cs

View workflow job for this annotation

GitHub Actions / build

Type 'ServerExecutionBase' in interface list is not an interface
{
Task HandleAsync(TDomainEvent query, CancellationToken cancellation);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Microsoft.Extensions.DependencyInjection;
using Shared.Features.CQRS.Command;
using Shared.Features.CQRS.DomainEvent;
using Shared.Features.CQRS.Query;
using Shared.Kernel.BuildingBlocks.ModelValidation;
using Shared.Kernel.BuildingBlocks;
using Shared.Features.Server;

namespace Shared.Features.CQRS.IntegrationEvent
{
public class BaseIntegrationEventHandler : ServerExecutionBase
{
public IExecutionContext ExecutionContext { get; }
public ICommandDispatcher CommandDispatcher { get; }
public IQueryDispatcher QueryDispatcher { get; }
public IIntegrationEventDispatcher IntegrationEventDispatcher { get; }
public IDomainEventDispatcher DomainEventDispatcher { get; }
public IValidationService ValidationService { get; }

public BaseIntegrationEventHandler(IServiceProvider serviceProvider)
{
ExecutionContext = serviceProvider.GetRequiredService<IExecutionContext>();
CommandDispatcher = serviceProvider.GetRequiredService<ICommandDispatcher>();
QueryDispatcher = serviceProvider.GetRequiredService<IQueryDispatcher>();
IntegrationEventDispatcher = serviceProvider.GetRequiredService<IIntegrationEventDispatcher>();
DomainEventDispatcher = serviceProvider.GetRequiredService<IDomainEventDispatcher>();
ValidationService = serviceProvider.GetRequiredService<IValidationService>();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Shared.Features.CQRS.IntegrationEvent
{
public interface IIntegrationEventHandler<in TIntegrationEvent> : IInServerExecutionScope where TIntegrationEvent : IIntegrationEvent
public interface IIntegrationEventHandler<in TIntegrationEvent> : ServerExecutionBase where TIntegrationEvent : IIntegrationEvent

Check failure on line 6 in Source/Shared/Features/CQRS/IntegrationEvent/IIntegrationEventHandler.cs

View workflow job for this annotation

GitHub Actions / build

Type 'ServerExecutionBase' in interface list is not an interface

Check failure on line 6 in Source/Shared/Features/CQRS/IntegrationEvent/IIntegrationEventHandler.cs

View workflow job for this annotation

GitHub Actions / build

Type 'ServerExecutionBase' in interface list is not an interface
{
Task HandleAsync(TIntegrationEvent integrationEvent, CancellationToken cancellation);
}
Expand Down
14 changes: 11 additions & 3 deletions Source/Shared/Features/CQRS/Query/BaseQueryHandler.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
using Shared.Features.Server;
using Microsoft.Extensions.DependencyInjection;
using Shared.Features.CQRS.Command;
using Shared.Features.CQRS.DomainEvent;
using Shared.Features.CQRS.IntegrationEvent;
using Shared.Features.Server;
using Shared.Kernel.BuildingBlocks;
using Shared.Kernel.BuildingBlocks.ModelValidation;

namespace Shared.Features.CQRS.Query
{
public class BaseQueryHandler : IInServerExecutionScope
public class BaseQueryHandler : ServerExecutionBase
{
public IServerExecutionContext ExecutionContext { get; private set; }
public BaseQueryHandler(IServiceProvider serviceProvider) : base(serviceProvider)
{
}
}
}
2 changes: 1 addition & 1 deletion Source/Shared/Features/CQRS/Query/IQueryHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Shared.Features.CQRS.Query
{
public interface IQueryHandler<in TQuery, TQueryResult> : IInServerExecutionScope where TQuery : IQuery<TQueryResult>
public interface IQueryHandler<in TQuery, TQueryResult> : ServerExecutionBase where TQuery : IQuery<TQueryResult>

Check failure on line 5 in Source/Shared/Features/CQRS/Query/IQueryHandler.cs

View workflow job for this annotation

GitHub Actions / build

Type 'ServerExecutionBase' in interface list is not an interface
{
Task<TQueryResult> HandleAsync(TQuery query, CancellationToken cancellation);
}
Expand Down
24 changes: 18 additions & 6 deletions Source/Shared/Features/Server/BaseController.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Shared.Features.CQRS.Command;
using Shared.Features.CQRS.DomainEvent;
using Shared.Features.CQRS.IntegrationEvent;
using Shared.Features.CQRS.Query;
using Shared.Kernel.BuildingBlocks;
using Shared.Kernel.BuildingBlocks.ModelValidation;

namespace Shared.Features.Server
{
public class BaseController : ControllerBase, InServerExecutionScopeBase
public class BaseController : ControllerBase, ServerExecutionBase

Check failure on line 12 in Source/Shared/Features/Server/BaseController.cs

View workflow job for this annotation

GitHub Actions / build

Class 'BaseController' cannot have multiple base classes: 'ControllerBase' and 'ServerExecutionBase'
{
public IServerExecutionContext ExecutionContext { get; }

protected readonly IValidationService validationService;
public IExecutionContext ExecutionContext { get; }
public ICommandDispatcher CommandDispatcher { get; }
public IQueryDispatcher QueryDispatcher { get; }
public IIntegrationEventDispatcher IntegrationEventDispatcher { get; }
public IDomainEventDispatcher DomainEventDispatcher { get; }
public IValidationService ValidationService { get; }

public BaseController(IServiceProvider serviceProvider)
{
ExecutionContext = serviceProvider.GetRequiredService<IServerExecutionContext>();
validationService = serviceProvider.GetRequiredService<IValidationService>();
ExecutionContext = serviceProvider.GetRequiredService<IExecutionContext>();
CommandDispatcher = serviceProvider.GetRequiredService<ICommandDispatcher>();
QueryDispatcher = serviceProvider.GetRequiredService<IQueryDispatcher>();
IntegrationEventDispatcher = serviceProvider.GetRequiredService<IIntegrationEventDispatcher>();
DomainEventDispatcher = serviceProvider.GetRequiredService<IDomainEventDispatcher>();
ValidationService = serviceProvider.GetRequiredService<IValidationService>();
}
}
}
8 changes: 4 additions & 4 deletions Source/Shared/Features/Server/ExecutionContext/Registrator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@ public static class Registrator
public static IServiceCollection AddServerExecutionContext(this IServiceCollection services)
{
services.AddHttpContextAccessor();
services.AddScoped<ServiceExecutionContextMiddleware>();
services.AddScoped<IServerExecutionContext, ServerExecutionContext>(ServerExecutionContext.CreateInstance);
services.AddScoped<ServerExecutionContextMiddleware>();
services.AddScoped<IExecutionContext, ServerExecutionContext>(ServerExecutionContext.CreateInstance);
return services;
}

public static IApplicationBuilder UseServerExecutionContextMiddleware(this IApplicationBuilder app)
{
app.UseMiddleware<ServiceExecutionContextMiddleware>();
app.UseMiddleware<ServerExecutionContextMiddleware>();

return app;
}
}


public class ServiceExecutionContextMiddleware : IMiddleware
public class ServerExecutionContextMiddleware : IMiddleware
{
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,6 @@ public void InitializeInstance(HttpContext httpContext)
TenantId = httpContext.User.GetTenantId<Guid>();
TenantPlan = httpContext.User.GetTenantSubscriptionPlanType();
TenantRole = httpContext.User.GetTenantRole();
CommandDispatcher = httpContext.RequestServices.GetRequiredService<ICommandDispatcher>();
QueryDispatcher = httpContext.RequestServices.GetRequiredService<IQueryDispatcher>();
IntegrationEventDispatcher = httpContext.RequestServices.GetRequiredService<IIntegrationEventDispatcher>();
DomainEventDispatcher = httpContext.RequestServices.GetRequiredService<IDomainEventDispatcher>();
}
}
}
19 changes: 0 additions & 19 deletions Source/Shared/Features/Server/IInServerExecutionScope.cs

This file was deleted.

19 changes: 0 additions & 19 deletions Source/Shared/Features/Server/InServerExecutionScopeBase.cs

This file was deleted.

Loading

0 comments on commit 0bbb374

Please sign in to comment.