Skip to content

Commit

Permalink
Merge pull request #304 from meysamhadeli/refactor/refactor-analyzer-…
Browse files Browse the repository at this point in the history
…configs

refactor/refactor analyzer configs
  • Loading branch information
meysamhadeli authored Sep 16, 2024
2 parents f9eb00c + fa3b184 commit b349d5e
Show file tree
Hide file tree
Showing 19 changed files with 1,080 additions and 621 deletions.
1,087 changes: 699 additions & 388 deletions .editorconfig

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions .github/actions/build/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ runs:
# restore root solution
run: dotnet restore

# npm install, runs `prepare` script automatically in the initialize step
- name: Install NPM Dependencies
shell: bash
if: success()
run: npm install

- name: Format Service
shell: bash
if: ${{ success()}}
run: |
npm run ci-format
- name: Build Service
shell: bash
if: ${{ success()}}
Expand Down
4 changes: 3 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@
<PropertyGroup>
<RunAnalyzersDuringBuild>true</RunAnalyzersDuringBuild>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<AnalysisMode>All</AnalysisMode>
<CodeAnalysisTreatWarningsAsErrors>false</CodeAnalysisTreatWarningsAsErrors>
<AnalysisLevel>latest-Recommended</AnalysisLevel>
<AnalysisMode>Recommended</AnalysisMode>
</PropertyGroup>

</Project>
24 changes: 22 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
- [Structure of Project](#structure-of-project)
- [Development Setup](#development-setup)
- [Dotnet Tools Packages](#dotnet-tools-packages)
- [Husky](#husky)
- [Upgrade Nuget Packages](#upgrade-nuget-packages)
- [How to Run](#how-to-run)
- [Config Certificate](#config-certificate)
- [Docker Compose](#docker-compose)
Expand All @@ -47,7 +49,7 @@
- :sparkle: Using `Postgres` for `write side` of some microservices.
- :sparkle: Using `MongoDB` for `read side` of some microservices.
- :sparkle: Using `Event Store` for `write side` of Booking-Microservice to store all `historical state` of aggregate.
- :sparkle: Using `Inbox Pattern` for ensuring message idempotency for receiver and `Exactly once Delivery`.
- :sparkle: Using `Inbox Pattern` for ensuring message idempotency for receiver and `Exactly once Delivery`.
- :sparkle: Using `Outbox Pattern` for ensuring no message is lost and there is at `At Least One Delivery`.
- :sparkle: Using `Unit Testing` for testing small units and mocking our dependencies with `Nsubstitute`.
- :sparkle: Using `End-To-End Testing` and `Integration Testing` for testing `features` with all dependencies using `testcontainers`.
Expand Down Expand Up @@ -159,7 +161,7 @@ Using the CQRS pattern, we cut each business functionality into vertical slices,
## Development Setup

### Dotnet Tools Packages
For installing our requirement package with .NET cli tools, we need to install `dotnet tool manifest`.
For installing our requirement packages with .NET cli tools, we need to install `dotnet tool manifest`.
```bash
dotnet new tool-manifest
```
Expand All @@ -168,6 +170,24 @@ And after that we can restore our dotnet tools packages with .NET cli tools from
dotnet tool restore
```

### Husky
Here we use `husky` to handel some pre commit rules and we used `conventional commits` rules and `formatting` as pre commit rules, here in [package.json](./package.json). of course, we can add more rules for pre commit in future. (find more about husky in the [documentation](https://typicode.github.io/husky/get-started.html))
We need to install `husky` package for `manage` `pre commits hooks` and also I add two packages `@commitlint/cli` and `@commitlint/config-conventional` for handling conventional commits rules in [package.json](./package.json).
Run the command bellow in the root of project to install all npm dependencies related to husky:

```bash
npm install
```

> Note: In the root of project we have `.husky` folder and it has `commit-msg` file for handling conventional commits rules with provide user friendly message and `pre-commit` file that we can run our `scripts` as a `pre-commit` hooks. that here we call `format` script from [package.json](./package.json) for formatting purpose.
### Upgrade Nuget Packages
For upgrading our nuget packages to last version, we use the great package [dotnet-outdated](https://github.com/dotnet-outdated/dotnet-outdated).
Run the command below in the root of project to upgrade all of packages to last version:
```bash
dotnet outdated -u
```

## How to Run

> ### Config Certificate
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"scripts": {
"prepare": "husky && dotnet tool restore",
"format": "dotnet format booking-microservices-sample.sln --severity error --verbosity detailed",
"ci-format": "dotnet format booking-microservices-sample.sln --verify-no-changes --severity error --verbosity detailed",
"upgrade-packages": "dotnet outdated --upgrade"
},
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions src/BuildingBlocks/BuildingBlocks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<PackageReference Include="Grpc.Core.Testing" Version="2.46.6" />
<PackageReference Include="EasyCaching.Core" Version="1.9.2" />
<PackageReference Include="EasyCaching.InMemory" Version="1.9.2" />
<PackageReference Include="EasyNetQ.Management.Client" Version="2.0.0" />
<PackageReference Include="EasyNetQ.Management.Client" Version="3.0.0" />
<PackageReference Include="EFCore.NamingConventions" Version="8.0.3" />
<PackageReference Include="Figgle" Version="0.5.1" />
<PackageReference Include="FluentValidation" Version="11.10.0" />
Expand Down Expand Up @@ -51,7 +51,7 @@
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="OpenTelemetry.Contrib.Instrumentation.MassTransit" Version="1.0.0-beta2" />
<PackageReference Include="Scrutor" Version="4.2.2" />
<PackageReference Include="Sentry.Serilog" Version="4.9.0" />
<PackageReference Include="Sentry.Serilog" Version="4.10.2" />
<PackageReference Include="Serilog" Version="4.0.1" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
<PackageReference Include="Serilog.Enrichers.Span" Version="3.1.0" />
Expand Down
10 changes: 5 additions & 5 deletions src/BuildingBlocks/Core/EventDispatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ await _persistMessageProcessor.PublishMessageAsync(
switch (events)
{
case IReadOnlyList<IDomainEvent> domainEvents:
{
var integrationEvents = await MapDomainEventToIntegrationEventAsync(domainEvents)
{
var integrationEvents = await MapDomainEventToIntegrationEventAsync(domainEvents)
.ConfigureAwait(false);

await PublishIntegrationEvent(integrationEvents);
break;
}
await PublishIntegrationEvent(integrationEvents);
break;
}

case IReadOnlyList<IIntegrationEvent> integrationEvents:
await PublishIntegrationEvent(integrationEvents);
Expand Down
51 changes: 30 additions & 21 deletions src/BuildingBlocks/EFCore/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,40 @@ namespace BuildingBlocks.EFCore;

public static class Extensions
{
public static IServiceCollection AddCustomDbContext<TContext>(
this IServiceCollection services)
where TContext : DbContext, IDbContext
public static IServiceCollection AddCustomDbContext<TContext>(this IServiceCollection services)
where TContext : DbContext, IDbContext
{
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);

services.AddValidateOptions<PostgresOptions>();

services.AddDbContext<TContext>((sp, options) =>
{
var postgresOptions = sp.GetRequiredService<PostgresOptions>();
services.AddDbContext<TContext>(
(sp, options) =>
{
var postgresOptions = sp.GetRequiredService<PostgresOptions>();

Guard.Against.Null(options, nameof(postgresOptions));
Guard.Against.Null(options, nameof(postgresOptions));

options.UseNpgsql(postgresOptions?.ConnectionString,
dbOptions =>
{
dbOptions.MigrationsAssembly(typeof(TContext).Assembly.GetName().Name);
})
// https://github.com/efcore/EFCore.NamingConventions
.UseSnakeCaseNamingConvention();
});
options.UseNpgsql(
postgresOptions?.ConnectionString,
dbOptions =>
{
dbOptions.MigrationsAssembly(typeof(TContext).Assembly.GetName().Name);
})
// https://github.com/efcore/EFCore.NamingConventions
.UseSnakeCaseNamingConvention();
});

services.AddScoped<IDbContext>(provider => provider.GetService<TContext>());

return services;
}

public static IApplicationBuilder UseMigration<TContext>(this IApplicationBuilder app, IWebHostEnvironment env)
where TContext : DbContext, IDbContext
public static IApplicationBuilder UseMigration<TContext>(
this IApplicationBuilder app,
IWebHostEnvironment env
)
where TContext : DbContext, IDbContext
{
MigrateDatabaseAsync<TContext>(app.ApplicationServices).GetAwaiter().GetResult();

Expand All @@ -62,22 +66,24 @@ public static IApplicationBuilder UseMigration<TContext>(this IApplicationBuilde
public static void FilterSoftDeletedProperties(this ModelBuilder modelBuilder)
{
Expression<Func<IAggregate, bool>> filterExpr = e => !e.IsDeleted;

foreach (var mutableEntityType in modelBuilder.Model.GetEntityTypes()
.Where(m => m.ClrType.IsAssignableTo(typeof(IEntity))))
{
// modify expression to handle correct child type
var parameter = Expression.Parameter(mutableEntityType.ClrType);

var body = ReplacingExpressionVisitor
.Replace(filterExpr.Parameters.First(), parameter, filterExpr.Body);

var lambdaExpression = Expression.Lambda(body, parameter);

// set filter
mutableEntityType.SetQueryFilter(lambdaExpression);
}
}


//ref: https://andrewlock.net/customising-asp-net-core-identity-ef-core-naming-conventions-for-postgresql/
// ref: https://andrewlock.net/customising-asp-net-core-identity-ef-core-naming-conventions-for-postgresql/
public static void ToSnakeCaseTables(this ModelBuilder modelBuilder)
{
foreach (var entity in modelBuilder.Model.GetEntityTypes())
Expand All @@ -86,7 +92,9 @@ public static void ToSnakeCaseTables(this ModelBuilder modelBuilder)
entity.SetTableName(entity.GetTableName()?.Underscore());

var tableObjectIdentifier =
StoreObjectIdentifier.Table(entity.GetTableName()?.Underscore()!, entity.GetSchema());
StoreObjectIdentifier.Table(
entity.GetTableName()?.Underscore()!,
entity.GetSchema());

// Replace column names
foreach (var property in entity.GetProperties())
Expand All @@ -107,7 +115,7 @@ public static void ToSnakeCaseTables(this ModelBuilder modelBuilder)
}

private static async Task MigrateDatabaseAsync<TContext>(IServiceProvider serviceProvider)
where TContext : DbContext, IDbContext
where TContext : DbContext, IDbContext
{
using var scope = serviceProvider.CreateScope();

Expand All @@ -119,6 +127,7 @@ private static async Task SeedDataAsync(IServiceProvider serviceProvider)
{
using var scope = serviceProvider.CreateScope();
var seeders = scope.ServiceProvider.GetServices<IDataSeeder>();

foreach (var seeder in seeders)
{
await seeder.SeedAllAsync();
Expand Down
4 changes: 2 additions & 2 deletions src/BuildingBlocks/EventStoreDB/Events/EventTypeMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static void AddCustomMap(Type eventType, string mappedEventTypeName)

public static string ToName(Type eventType) => Instance.typeNameMap.GetOrAdd(eventType, _ =>
{
var eventTypeName = eventType.FullName!.Replace(".", "_");
var eventTypeName = eventType.FullName!.Replace(".", "_", StringComparison.CurrentCulture);

Instance.typeMap.AddOrUpdate(eventTypeName, eventType, (_, _) => eventType);

Expand All @@ -31,7 +31,7 @@ public static string ToName(Type eventType) => Instance.typeNameMap.GetOrAdd(eve

public static Type? ToType(string eventTypeName) => Instance.typeMap.GetOrAdd(eventTypeName, _ =>
{
var type = TypeProvider.GetFirstMatchingTypeFromCurrentDomainAssembly(eventTypeName.Replace("_", "."));
var type = TypeProvider.GetFirstMatchingTypeFromCurrentDomainAssembly(eventTypeName.Replace("_", ".", StringComparison.CurrentCulture));

if (type == null)
return null;
Expand Down
2 changes: 1 addition & 1 deletion src/BuildingBlocks/Jwt/AuthHeaderHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage reques
{
var token = (_httpContext?.HttpContext?.Request.Headers["Authorization"])?.ToString();

request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token?.Replace("Bearer ", ""));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token?.Replace("Bearer ", "", StringComparison.CurrentCulture));

return base.SendAsync(request, cancellationToken);
}
Expand Down
3 changes: 2 additions & 1 deletion src/BuildingBlocks/Logging/Extensions.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Globalization;
using System.Text;
using BuildingBlocks.Web;
using Microsoft.AspNetCore.Builder;
Expand Down Expand Up @@ -44,7 +45,7 @@ public static WebApplicationBuilder AddCustomSerilog(this WebApplicationBuilder
new ElasticsearchSinkOptions(new Uri(logOptions.Elastic.ElasticServiceUrl))
{
AutoRegisterTemplate = true,
IndexFormat = $"{appOptions.Name}-{environment?.ToLower()}"
IndexFormat = $"{appOptions.Name}-{environment?.ToLower(CultureInfo.CurrentCulture)}"
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/BuildingBlocks/Mongo/ImmutablePocoConvention.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ private static List<PropertyInfo> GetMatchingProperties(

private static bool ParameterMatchProperty(ParameterInfo parameter, PropertyInfo property)
{
return string.Equals(property.Name, parameter.Name, System.StringComparison.InvariantCultureIgnoreCase)
return string.Equals(property.Name, parameter.Name, StringComparison.OrdinalIgnoreCase)
&& parameter.ParameterType == property.PropertyType;
}

Expand Down
3 changes: 2 additions & 1 deletion src/BuildingBlocks/Mongo/MongoDbContext.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Globalization;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Conventions;
Expand Down Expand Up @@ -42,7 +43,7 @@ private static void RegisterConventions()

public IMongoCollection<T> GetCollection<T>(string? name = null)
{
return Database.GetCollection<T>(name ?? typeof(T).Name.ToLower());
return Database.GetCollection<T>(name ?? typeof(T).Name.ToLower(CultureInfo.CurrentCulture));
}

public void Dispose()
Expand Down
Loading

0 comments on commit b349d5e

Please sign in to comment.