Skip to content

Commit 3497cea

Browse files
Reduced projects coupling
1 parent 4ad6e5c commit 3497cea

File tree

91 files changed

+323
-369
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+323
-369
lines changed

README.md

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,24 @@ TaskHub.Shared contains the fundamental components and patterns used across all
1515
- **TaskHub.Shared.Response** — Unified result system (`Result`, `ValueResult<T>`, `ResultFactory`) for consistent success/error handling.
1616
- **TaskHub.Shared.Services.Abstractions** — Common service interfaces for dependency inversion.
1717
- **TaskHub.Shared.Events.Abstractions** — Domain event abstractions for cross-service communication and eventual consistency patterns.
18-
- **TaskHub.Shared.Redis** — Integration with Redis for caching and distributed state management.
1918

2019
## Persistence
2120
- **TaskHub.Shared.Persistence.Abstractions** — Interfaces for read/write repositories, unit of work, and persistence contracts.
2221
- **TaskHub.Shared.Infrastructure.EfCore** — EF Core helpers, base configurations, and interceptors for database integration.
22+
- **TaskHub.Shared.Redis** — Integration with Redis for caching and distributed state management.
2323

2424
## Authorization
2525
- **TaskHub.Shared.Authorization.Abstractions** — Authorization contracts, roles/permissions abstractions, and policies shared across services.
2626
- **TaskHub.Shared.Authorization.Identity** — Identity-related models and helpers used by TaskHub services (users, claims, roles).
2727

28-
2928
## Tools
3029
- **TaskHub.Shared.Versioning** — Shared conventions and helpers for API versioning across TaskHub microservices.
3130
- **TaskHub.Shared.RateLimiter** — Reusable rate-limiting primitives and policies for protecting APIs and internal pipelines.
3231

33-
3432
## Pipeline
3533
- **TaskHub.Shared.Commands.Abstractions** — Abstractions for the command pipeline (interfaces for command handlers, behaviors, buses).
3634
- **TaskHub.Shared.Commands.Bus** — Default in-process command bus implementation with behavior orchestration (behaviors pipeline, cross-cutting concerns).
3735

38-
3936
## Geocoding
4037
- **TaskHub.Shared.GeoCoding.Abstractions** — Abstractions for geocoding providers.
4138
- **TaskHub.Shared.GeoCoding.Nominatim** — Implementation of the geocoding service using the Nominatim API.
@@ -61,11 +58,9 @@ TaskHub.Shared contains the fundamental components and patterns used across all
6158
- **TaskHub.Shared.Refactoring.Abstractions** — Abstractions for service refactoring.
6259
- **TaskHub.Shared.Refactoring.Implementation** — Implementations for service refactoring and dynamic dependency resolution.
6360

64-
6561
## Swagger / OpenAPI
6662
- **TaskHub.Shared.Swagger** — Common Swagger / OpenAPI configuration for ASP.NET Core services (conventions, filters, defaults).
6763

68-
6964
## Bootstrapping
7065
- **TaskHub.Shared.Bootstraper.Basic** — Basic service bootstrapping (dependency injection, configuration, logging).
7166
- **TaskHub.Shared.Bootstraper.Full** — Comprehensive service bootstrapping (all features, advanced configuration, etc.).

Shared.slnx

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,20 @@
88
<File Path=".nuget/publish.ps1" />
99
</Folder>
1010
<Folder Name="/Abstractions/">
11-
<Project Path="TaskHub.Shared.Persistence.Abstractions/TaskHub.Shared.Persistence.Abstractions.csproj" />
12-
<Project Path="TaskHub.Shared.Primitives/TaskHub.Shared.Primitives.csproj" />
11+
<Project Path="TaskHub.Shared.Primitives/TaskHub.Shared.ValueObjects.csproj" />
1312
<Project Path="TaskHub.Shared.Response/TaskHub.Shared.Response.csproj" />
14-
<Project Path="TaskHub.Shared.Services.Abstractions/TaskHub.Shared.Services.Abstractions.csproj" Id="cbdd1627-836b-4ce6-be62-5a69e567158d" />
13+
<Project Path="TaskHub.Shared.Services.Abstractions/TaskHub.Shared.Services.Abstractions.csproj" />
1514
</Folder>
1615
<Folder Name="/Authorization/">
17-
<Project Path="TaskHub.Shared.Authorization.Abstractions/TaskHub.Shared.Authorization.Abstractions.csproj" Id="f264dfba-c7d1-4ae9-b715-a4ae655a2b94" />
18-
<Project Path="TaskHub.Shared.Authorization.Identity/TaskHub.Shared.Authorization.Identity.csproj" Id="e504d3d9-9465-43fd-a1c8-86b896225084" />
16+
<Project Path="TaskHub.Shared.Authorization.Abstractions/TaskHub.Shared.Authorization.Abstractions.csproj" />
17+
<Project Path="TaskHub.Shared.Authorization.Identity/TaskHub.Shared.Authorization.Identity.csproj" />
1918
</Folder>
2019
<Folder Name="/Bootstraping/">
2120
<Project Path="TaskHub.Shared.Bootstraper.Basic/TaskHub.Shared.Bootstraper.Basic.csproj" />
2221
<Project Path="TaskHub.Shared.Bootstraper.Full/TaskHub.Shared.Bootstraper.Full.csproj" />
2322
</Folder>
2423
<Folder Name="/Commands/">
25-
<Project Path="TaskHub.Shared.Commands.Abstractions/TaskHub.Shared.Commands.Abstractions.csproj" Id="6db7c998-24a5-4b97-8aae-a3e725e04d25" />
24+
<Project Path="TaskHub.Shared.Commands.Abstractions/TaskHub.Shared.Commands.Abstractions.csproj" />
2625
<Project Path="TaskHub.Shared.Commands.Bus/TaskHub.Shared.Commands.Bus.csproj" />
2726
</Folder>
2827
<Folder Name="/Domain/">
@@ -32,34 +31,36 @@
3231
<Project Path="TaskHub.Shared.Events.Abstractions/TaskHub.Shared.Events.Abstractions.csproj" />
3332
</Folder>
3433
<Folder Name="/GeoCoding/">
35-
<Project Path="TaskHub.Shared.GeoCoding.Abstractions/TaskHub.Shared.GeoCoding.Abstractions.csproj" Id="8d85e82f-7eec-413b-a428-eac4c5eb2fab" />
34+
<Project Path="TaskHub.Shared.GeoCoding.Abstractions/TaskHub.Shared.GeoCoding.Abstractions.csproj" />
3635
<Project Path="TaskHub.Shared.GeoCoding.Nominatim/TaskHub.Shared.GeoCoding.Nominatim.csproj" />
3736
</Folder>
38-
<Folder Name="/Infrastructure/">
39-
<Project Path="TaskHub.Shared.Infrastructure.EfCore/TaskHub.Shared.Infrastructure.EfCore.csproj" />
40-
</Folder>
4137
<Folder Name="/Observability/" />
4238
<Folder Name="/Observability/Logger/">
43-
<Project Path="TaskHub.Observability.Logger/TaskHub.Observability.Logger.csproj" Id="74dac548-da4e-4be6-841c-da55189b8c09" />
39+
<Project Path="TaskHub.Observability.Logger/TaskHub.Observability.Logger.csproj" />
4440
</Folder>
4541
<Folder Name="/Observability/Metrics/">
4642
<Project Path="TaskHub.Observability.Metrics.Abstractions/TaskHub.Observability.Metrics.Abstractions.csproj" />
47-
<Project Path="TaskHub.Observability.Metrics.Implementation/TaskHub.Observability.Metrics.Implementation.csproj" Id="33b30daf-9744-4a33-803d-c360afab8341" />
43+
<Project Path="TaskHub.Observability.Metrics.Implementation/TaskHub.Observability.Metrics.Implementation.csproj" />
4844
</Folder>
4945
<Folder Name="/Observability/OpenTelemetry/">
5046
<Project Path="TaskHub.Observability.OpenTelemetry/TaskHub.Observability.OpenTelemetry.csproj" />
5147
</Folder>
5248
<Folder Name="/Observability/Traces/">
53-
<Project Path="TaskHub.Observability.Traces/TaskHub.Observability.Traces.csproj" Id="cb48c92f-bb0c-432d-a8e2-03599ef12ae4" />
49+
<Project Path="TaskHub.Observability.Traces/TaskHub.Observability.Traces.csproj" />
50+
</Folder>
51+
<Folder Name="/Persistence/">
52+
<Project Path="TaskHub.Shared.Persistence.EntityFramework/TaskHub.Shared.Persistence.EntityFramework.csproj" />
53+
<Project Path="TaskHub.Shared.Persistence.Outbox/TaskHub.Shared.Persistence.Outbox.csproj" />
54+
<Project Path="TaskHub.Shared.Persistence.Redis/TaskHub.Shared.Persistence.Redis.csproj" />
55+
<Project Path="TaskHub.Shared.Persistence.Repository/TaskHub.Shared.Persistence.Repository.csproj" />
5456
</Folder>
5557
<Folder Name="/Refactoring/">
56-
<Project Path="TaskHub.Shared.Refactoring.Abstractions/TaskHub.Shared.Refactoring.Abstractions.csproj" Id="c88a066f-c702-4671-bb52-c5293696fc0c" />
57-
<Project Path="TaskHub.Shared.Refactoring.Implementation/TaskHub.Shared.Refactoring.Implementation.csproj" Id="6fe83e8e-6b67-48d4-a433-e52e282477ac" />
58+
<Project Path="TaskHub.Shared.Refactoring.Abstractions/TaskHub.Shared.Refactoring.Abstractions.csproj" />
59+
<Project Path="TaskHub.Shared.Refactoring.Implementation/TaskHub.Shared.Refactoring.Implementation.csproj" />
5860
</Folder>
5961
<Folder Name="/Tools/">
60-
<Project Path="TaskHub.Shared.RateLimiter/TaskHub.Shared.RateLimiter.csproj" Id="6e4d4c7b-0df0-460e-8653-8123bc540fc6" />
61-
<Project Path="TaskHub.Shared.Redis/TaskHub.Shared.Redis.csproj" Id="5fc5938a-a4d2-4fee-99cc-5d9cf54e0645" />
62-
<Project Path="TaskHub.Shared.Swagger/TaskHub.Shared.Swagger.csproj" Id="b945e948-fe0b-4724-8f55-cbd0be83e924" />
63-
<Project Path="TaskHub.Shared.Versioning/TaskHub.Shared.Versioning.csproj" Id="f205e5d7-23fb-43ea-9007-9e9d9b9042c0" />
62+
<Project Path="TaskHub.Shared.RateLimiter/TaskHub.Shared.RateLimiter.csproj" />
63+
<Project Path="TaskHub.Shared.Swagger/TaskHub.Shared.Swagger.csproj" />
64+
<Project Path="TaskHub.Shared.Versioning/TaskHub.Shared.Versioning.csproj" />
6465
</Folder>
6566
</Solution>
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
using TaskHub.Shared.Primitives.ValueObjects;
2-
using TaskHub.Shared.Services.Abstractions;
1+
using TaskHub.Shared.Services.Abstractions;
32

43
namespace TaskHub.Shared.Authorization.Abstractions;
54

6-
public interface ITokenService<T> : IService
5+
public interface ITokenService : IService
76
{
8-
Task<AuthToken> GenerateAsync(T user, IList<string> roles);
7+
Task<string> GenerateAsync(string user, IList<string> roles, string securityStamp);
98
}
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
using TaskHub.Shared.Primitives.ValueObjects;
2-
using TaskHub.Shared.Refactoring.Abstractions;
1+
using TaskHub.Shared.Refactoring.Abstractions;
32
using TaskHub.Shared.Services.Abstractions;
43

54
namespace TaskHub.Shared.Authorization.Abstractions;
65

76
[Unresolvable]
8-
public interface IUserService : IService
7+
public interface IUserService<T> : IService where T : IEquatable<T>
98
{
10-
UserId UserId { get; }
9+
T UserId { get; }
1110
}

TaskHub.Shared.Authorization.Abstractions/TaskHub.Shared.Authorization.Abstractions.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
<Description>Authorization contracts, roles/permissions abstractions, and policies shared across services.</Description>
44
</PropertyGroup>
55
<ItemGroup>
6-
<ProjectReference Include="..\TaskHub.Shared.Primitives\TaskHub.Shared.Primitives.csproj" />
76
<ProjectReference Include="..\TaskHub.Shared.Refactoring.Abstractions\TaskHub.Shared.Refactoring.Abstractions.csproj" />
87
<ProjectReference Include="..\TaskHub.Shared.Services.Abstractions\TaskHub.Shared.Services.Abstractions.csproj" />
98
</ItemGroup>

TaskHub.Shared.Authorization.Identity/Bootstrap/AddAppIndentity.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
using Microsoft.AspNetCore.Identity;
22
using Microsoft.EntityFrameworkCore;
33
using Microsoft.Extensions.DependencyInjection;
4-
using TaskHub.Shared.Authorization.Identity.Models;
54

65
namespace TaskHub.Shared.Authorization.Identity.Bootstrap;
76

87
public static class AddAppAuthorization
98
{
10-
public static void AddAppIdentity<TContext>(this IServiceCollection services) where TContext : DbContext
9+
public static void AddAppIdentity<TContext, TIdType>(this IServiceCollection services)
10+
where TContext : DbContext
11+
where TIdType : IEquatable<TIdType>
1112
{
12-
services.AddIdentityCore<AppUser>(opt =>
13+
services.AddIdentityCore<IdentityUser<TIdType>>(opt =>
1314
{
1415
opt.Password.RequiredLength = 6;
1516
opt.Password.RequireNonAlphanumeric = false;
1617
opt.User.RequireUniqueEmail = true;
1718
opt.SignIn.RequireConfirmedEmail = true;
1819
})
19-
.AddRoles<UserRole>()
20+
.AddRoles<IdentityRole<TIdType>>()
2021
.AddEntityFrameworkStores<TContext>()
2122
.AddSignInManager()
2223
.AddDefaultTokenProviders();

TaskHub.Shared.Authorization.Identity/Bootstrap/AuthorizationBootsrap.cs

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
using Microsoft.AspNetCore.Authentication.JwtBearer;
2+
using Microsoft.AspNetCore.Http;
23
using Microsoft.Extensions.Caching.Distributed;
34
using Microsoft.Extensions.DependencyInjection;
5+
using Microsoft.IdentityModel.Tokens;
46
using System.Security.Claims;
7+
using TaskHub.Shared.Authorization.Abstractions;
8+
using TaskHub.Shared.Authorization.Identity.Exceptions;
59
using TaskHub.Shared.Authorization.Identity.Options;
10+
using TaskHub.Shared.Authorization.Identity.Services;
611

712
namespace TaskHub.Shared.Authorization.Identity.Bootstrap;
813

@@ -18,9 +23,22 @@ public static void AddAppAuthorization(this IServiceCollection services, Action<
1823
o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
1924
}).AddJwtBearer(o =>
2025
{
21-
o.MapInboundClaims = true;
22-
o.IncludeErrorDetails = true;
23-
o.TokenValidationParameters = options.ValidationParameters;
26+
o.MapInboundClaims = options.MapInboundClaims;
27+
o.IncludeErrorDetails = options.IncludeErrorDetails;
28+
o.TokenValidationParameters = new()
29+
{
30+
ValidateIssuerSigningKey = options.ValidateSigningKey,
31+
IssuerSigningKey = new SymmetricSecurityKey(Convert.FromBase64String(options.SigningKey)),
32+
ValidateIssuer = options.ValidateIssuer,
33+
ValidIssuer = options.Issuer,
34+
ValidateAudience = options.ValidateAudience,
35+
ValidAudience = options.Audience,
36+
ValidateLifetime = options.ValidateLifetime,
37+
RequireSignedTokens = options.RequireSignedTokens,
38+
RequireExpirationTime = options.RequireExpirationTime,
39+
ValidAlgorithms = [SecurityAlgorithms.HmacSha256],
40+
ClockSkew = TimeSpan.FromSeconds(options.ClockSkew),
41+
};
2442
o.Events = new()
2543
{
2644
OnTokenValidated = async ctx =>
@@ -51,4 +69,15 @@ public static void AddAppAuthorization(this IServiceCollection services, Action<
5169
};
5270
});
5371
}
72+
73+
public static void AddAppUserService<T>(this IServiceCollection services, Func<ClaimsPrincipal, T> resolveUserId)
74+
where T : IEquatable<T>
75+
{
76+
services.AddScoped<IUserService<T>>(sp =>
77+
{
78+
var http = sp.GetRequiredService<IHttpContextAccessor>();
79+
var user = http.HttpContext?.User ?? throw new AuthorizationException("No HttpContext");
80+
return new UserService<T>(resolveUserId(user));
81+
});
82+
}
5483
}

TaskHub.Shared.Authorization.Identity/Bootstrap/AuthorizationService.cs

Lines changed: 0 additions & 17 deletions
This file was deleted.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace TaskHub.Shared.Authorization.Identity.Exceptions;
2+
3+
public class AuthorizationException : Exception
4+
{
5+
public AuthorizationException(string message) : base(message) { }
6+
public AuthorizationException(string message, Exception exception) : base(message, exception) { }
7+
}

TaskHub.Shared.Authorization.Identity/Models/AppUser.cs

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)