chore: add hrynco common library solution

- add the standalone HrynCo.Common solution and projects
- include the shared common library source and tests
- add package metadata and a repo gitignore
This commit is contained in:
Anatolii Grynchuk
2026-05-01 00:17:34 +03:00
commit 85b362e8cd
38 changed files with 1452 additions and 0 deletions
@@ -0,0 +1,39 @@
namespace HrynCo.Common.HealthChecks;
using System.ComponentModel.DataAnnotations;
using HrynCo.Common.HealthChecks.Interfaces;
using Microsoft.Extensions.Diagnostics.HealthChecks;
public abstract class BaseConfigurationCheck<TOptions> : IConfigurationCheck
where TOptions : class
{
private readonly string _name;
private readonly TOptions _options;
protected BaseConfigurationCheck(TOptions options, string name)
{
_options = options;
_name = name;
}
public Task<HealthCheckResult> CheckConfigurationAsync(CancellationToken cancellationToken)
{
var context = new ValidationContext(_options);
var results = new List<ValidationResult>();
bool isValid = Validator.TryValidateObject(
_options,
context,
results,
true
);
if (!isValid)
{
string errors = string.Join("; ", results.Select(r => r.ErrorMessage));
return Task.FromResult(HealthCheckResult.Unhealthy($"{_name} configuration invalid: {errors}"));
}
return Task.FromResult(HealthCheckResult.Healthy($"{_name} configuration is valid."));
}
}
@@ -0,0 +1,30 @@
namespace HrynCo.Common.HealthChecks;
using HrynCo.Common.HealthChecks.Interfaces;
using Microsoft.Extensions.Diagnostics.HealthChecks;
public class CompositeHealthCheck : IHealthCheck
{
private readonly IConfigurationCheck _configCheck;
private readonly bool _configOnly;
private readonly IServiceHealthCheck _serviceCheck;
public CompositeHealthCheck(
IConfigurationCheck configCheck,
IServiceHealthCheck serviceCheck,
bool configOnly)
{
_configCheck = configCheck;
_serviceCheck = serviceCheck;
_configOnly = configOnly;
}
public Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context,
CancellationToken cancellationToken)
{
return _configOnly
? _configCheck.CheckConfigurationAsync(cancellationToken)
: _serviceCheck.CheckHealthAsync(cancellationToken);
}
}
@@ -0,0 +1,9 @@
namespace HrynCo.Common.HealthChecks.Defaults;
using System.ComponentModel.DataAnnotations;
public class DbOptions
{
[Required]
public string? ConnectionString { get; set; } = null!;
}
@@ -0,0 +1,21 @@
namespace HrynCo.Common.HealthChecks.Defaults;
using HrynCo.Common.HealthChecks.Interfaces;
using Microsoft.Extensions.Diagnostics.HealthChecks;
public sealed class DbServiceHealthCheck : IServiceHealthCheck
{
private readonly IDatabaseConnectionChecker _checker;
public DbServiceHealthCheck(IDatabaseConnectionChecker checker)
{
_checker = checker;
}
public async Task<HealthCheckResult> CheckHealthAsync(CancellationToken cancellationToken)
{
return await _checker.CanConnectAsync(cancellationToken)
? HealthCheckResult.Healthy("Database reachable")
: HealthCheckResult.Unhealthy("Database unreachable");
}
}
@@ -0,0 +1,9 @@
namespace HrynCo.Common.HealthChecks.Defaults;
using System.ComponentModel.DataAnnotations;
public class SeqOptions
{
[Required]
public string? ServerUrl { get; set; }
}
@@ -0,0 +1,8 @@
namespace HrynCo.Common.HealthChecks.Interfaces;
using Microsoft.Extensions.Diagnostics.HealthChecks;
public interface IConfigurationCheck
{
Task<HealthCheckResult> CheckConfigurationAsync(CancellationToken cancellationToken);
}
@@ -0,0 +1,6 @@
namespace HrynCo.Common.HealthChecks.Interfaces;
public interface IDatabaseConnectionChecker
{
Task<bool> CanConnectAsync(CancellationToken cancellationToken);
}
@@ -0,0 +1,8 @@
namespace HrynCo.Common.HealthChecks.Interfaces;
using Microsoft.Extensions.Diagnostics.HealthChecks;
public interface IServiceHealthCheck
{
Task<HealthCheckResult> CheckHealthAsync(CancellationToken cancellationToken);
}