diff --git a/Application/Application.csproj b/Application/Application.csproj
index f9b7155..0ae48f6 100644
--- a/Application/Application.csproj
+++ b/Application/Application.csproj
@@ -14,6 +14,8 @@
+
+
diff --git a/Application/Configuration/ConfigurationDependencyInjection.cs b/Application/Configuration/ConfigurationDependencyInjection.cs
deleted file mode 100644
index d1e0fab..0000000
--- a/Application/Configuration/ConfigurationDependencyInjection.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-
-namespace Musify.Application.Configuration
-{
- public static class ConfigurationDependencyInjection
- {
- public static void AddPlayListConfiguration(this IServiceCollection serviceDescriptors, IConfiguration configuration)
- {
- var playListConfiguration = PlayListConfiguration.Load(configuration);
- serviceDescriptors.AddSingleton(playListConfiguration);
- }
-
- public static void AddStorageConfiguration(this IServiceCollection serviceDescriptors, IConfiguration configuration)
- {
- var storageConfiguration = StorageConfiguration.Load(configuration);
- serviceDescriptors.AddSingleton(storageConfiguration);
- }
- }
-}
\ No newline at end of file
diff --git a/Application/Configuration/PlayListConfiguration.cs b/Application/Configuration/PlayListConfiguration.cs
index abaaeb0..18707cd 100644
--- a/Application/Configuration/PlayListConfiguration.cs
+++ b/Application/Configuration/PlayListConfiguration.cs
@@ -1,4 +1,4 @@
-using Microsoft.Extensions.Configuration;
+using System.ComponentModel.DataAnnotations;
namespace Musify.Application.Configuration
{
@@ -6,79 +6,55 @@ namespace Musify.Application.Configuration
{
public const string SectionName = "PlayListConfiguration";
+ [Required]
public Routes Routes { get; set; } = new Routes();
+ [Required]
public PicturesSizes PicturesSizes { get; set; } = new PicturesSizes();
-
- public static PlayListConfiguration Load(IConfiguration configuration)
- {
- var section = configuration.GetSection(SectionName).Get()
- ?? throw new InvalidOperationException($"{SectionName} configuration section not found.");
-
- Validate(section);
- return section;
- }
-
- static void Validate(PlayListConfiguration configuration)
- {
- EnsureValue(configuration.Routes.OriginalPictures, $"{SectionName}:BucketName");
- EnsureValue(configuration.Routes.SmallPictures, $"{SectionName}:Routes:SmallPictures");
- EnsureValue(configuration.Routes.MediumPictures, $"{SectionName}:Routes:MediumPictures");
- EnsureValue(configuration.Routes.LargePictures, $"{SectionName}:Routes:LargePictures");
- EnsureValue(configuration.Routes.PresetSmallPicture, $"{SectionName}:Routes:SmallPictures");
- EnsureValue(configuration.Routes.PresetMediumPicture, $"{SectionName}:Routes:MediumPictures");
- EnsureValue(configuration.Routes.PresetLargePicture, $"{SectionName}:Routes:LargePictures");
-
- EnsurePositiveValue(configuration.PicturesSizes.SmallPictureWidth, $"{SectionName}:SmallPictureWidth");
- EnsurePositiveValue(configuration.PicturesSizes.SmallPictureHeight, $"{SectionName}:SmallPictureHeight");
- EnsurePositiveValue(configuration.PicturesSizes.MediumPictureWidth, $"{SectionName}:MediumPictureWidth");
- EnsurePositiveValue(configuration.PicturesSizes.MediumPictureHeight, $"{SectionName}:MediumPictureHeight");
- EnsurePositiveValue(configuration.PicturesSizes.LargePictureWidth, $"{SectionName}:LargePictureWidth");
- EnsurePositiveValue(configuration.PicturesSizes.LargePictureHeight, $"{SectionName}:LargePictureHeight");
- }
-
- static void EnsureValue(string value, string name)
- {
- if (string.IsNullOrEmpty(value))
- throw new InvalidOperationException($"{name} configuration value not found.");
- }
-
- static void EnsurePositiveValue(int value, string name)
- {
- if (value < 1)
- throw new InvalidOperationException($"{name} configuration value must be a positive integer.");
- }
}
public class Routes
{
+ [Required]
public string OriginalPictures { get; set; } = "OriginalPictures";
+ [Required]
public string SmallPictures { get; set; } = "SmallPictures";
+ [Required]
public string MediumPictures { get; set; } = "MediumPictures";
+ [Required]
public string LargePictures { get; set; } = "LargePictures";
+ [Required]
public string PresetSmallPicture { get; set; } = "PresetSmallPicture.webp";
+ [Required]
public string PresetMediumPicture { get; set; } = "PresetMediumPicture.webp";
+ [Required]
public string PresetLargePicture { get; set; } = "PresetLargePicture.webp";
}
public class PicturesSizes
{
+ [Range(1, 1024)]
public int SmallPictureWidth { get; set; } = 128;
+ [Range(1, 1024)]
public int SmallPictureHeight { get; set; } = 128;
+ [Range(1, 1024)]
public int MediumPictureWidth { get; private set; } = 256;
+ [Range(1, 1024)]
public int MediumPictureHeight { get; private set; } = 256;
+ [Range(1, 1024)]
public int LargePictureWidth { get; private set; } = 512;
+ [Range(1, 1024)]
public int LargePictureHeight { get; private set; } = 512;
}
}
\ No newline at end of file
diff --git a/Application/Configuration/StorageConfiguration.cs b/Application/Configuration/StorageConfiguration.cs
index d02353f..70ea2b6 100644
--- a/Application/Configuration/StorageConfiguration.cs
+++ b/Application/Configuration/StorageConfiguration.cs
@@ -1,44 +1,28 @@
-using Microsoft.Extensions.Configuration;
+using System.ComponentModel.DataAnnotations;
namespace Musify.Application.Configuration
{
+#pragma warning disable CS8618
public class StorageConfiguration
{
public const string SectionName = "Storage";
- public string BucketName { get; set; } = string.Empty;
+ [Required]
+ public string BucketName { get; set; }
- public string ServiceUrl { get; set; } = string.Empty;
+ [Required]
+ public string ServiceUrl { get; set; }
- public string AccessKey { get; set; } = string.Empty;
+ [Required]
+ public string AccessKey { get; set; }
- public string SecretAccessKey { get; set; } = string.Empty;
+ [Required]
+ public string SecretAccessKey { get; set; }
+ [Required]
public bool ForcePathStyle { get; set; }
+ [Required]
public bool UseHttp { get; set; }
-
- public static StorageConfiguration Load(IConfiguration configuration)
- {
- var section = configuration.GetSection(SectionName).Get()
- ?? throw new InvalidOperationException($"{SectionName} configuration section not found.");
-
- Validate(section);
- return section;
- }
-
- static void Validate(StorageConfiguration configuration)
- {
- EnsureValue(configuration.BucketName, nameof(BucketName));
- EnsureValue(configuration.ServiceUrl, nameof(ServiceUrl));
- EnsureValue(configuration.AccessKey, nameof(AccessKey));
- EnsureValue(configuration.SecretAccessKey, nameof(SecretAccessKey));
- }
-
- static void EnsureValue(string value, string name)
- {
- if (string.IsNullOrEmpty(value))
- throw new InvalidOperationException($"{name} configuration value not found.");
- }
}
}
\ No newline at end of file
diff --git a/Application/DispatchR/DispatchRDependencyInjection.cs b/Application/DispatchR/DispatchRDependencyInjection.cs
deleted file mode 100644
index 2b058d8..0000000
--- a/Application/DispatchR/DispatchRDependencyInjection.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using DispatchR.Extensions;
-using Microsoft.Extensions.DependencyInjection;
-
-namespace Musify.Application.DispatchR
-{
- public static class DispatchRDependencyInjection
- {
- public static void AddDispatchR(this IServiceCollection serviceDescriptors)
- {
- serviceDescriptors.AddDispatchR(typeof(DispatchRDependencyInjection).Assembly);
- }
- }
-}
\ No newline at end of file
diff --git a/Infrastructure/Configuration/ConfigurationDependencyInjection.cs b/Infrastructure/Configuration/ConfigurationDependencyInjection.cs
deleted file mode 100644
index 815fb0f..0000000
--- a/Infrastructure/Configuration/ConfigurationDependencyInjection.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-
-namespace Musify.Infrastructure.Configuration
-{
- public static class ConfigurationDependencyInjection
- {
- public static void AddKeycloakConfiguration(this IServiceCollection serviceDescriptors, IConfiguration configuration)
- {
- var keycloakConfiguration = KeycloakConfiguration.Load(configuration);
- serviceDescriptors.AddSingleton(keycloakConfiguration);
- }
-
- public static void AddDatabaseConfiguration(this IServiceCollection serviceDescriptors, IConfiguration configuration)
- {
- var databaseConfiguration = DatabaseConfiguration.Load(configuration);
- serviceDescriptors.AddSingleton(databaseConfiguration);
- }
- }
-}
\ No newline at end of file
diff --git a/Infrastructure/Configuration/DatabaseConfiguration.cs b/Infrastructure/Configuration/DatabaseConfiguration.cs
index aeef73d..5996e49 100644
--- a/Infrastructure/Configuration/DatabaseConfiguration.cs
+++ b/Infrastructure/Configuration/DatabaseConfiguration.cs
@@ -1,31 +1,13 @@
-using Microsoft.Extensions.Configuration;
+using System.ComponentModel.DataAnnotations;
namespace Musify.Infrastructure.Configuration
{
+#pragma warning disable CS8618
public class DatabaseConfiguration
{
public const string SectionName = "Database";
- public string ConnectionString { get; set; } = string.Empty;
-
- public static DatabaseConfiguration Load(IConfiguration configuration)
- {
- var databaseConfiguration = configuration.GetSection(SectionName).Get()
- ?? throw new InvalidOperationException($"{SectionName} configuration section not found.");
-
- Validate(databaseConfiguration);
- return databaseConfiguration;
- }
-
- static void Validate(DatabaseConfiguration configuration)
- {
- EnsureValue(configuration.ConnectionString, nameof(configuration.ConnectionString));
- }
-
- static void EnsureValue(string value, string name)
- {
- if (string.IsNullOrEmpty(value))
- throw new InvalidOperationException($"{name} configuration value not found.");
- }
+ [Required]
+ public string ConnectionString { get; set; }
}
}
\ No newline at end of file
diff --git a/Infrastructure/Configuration/KeycloakConfiguration.cs b/Infrastructure/Configuration/KeycloakConfiguration.cs
index 23d0198..635dc07 100644
--- a/Infrastructure/Configuration/KeycloakConfiguration.cs
+++ b/Infrastructure/Configuration/KeycloakConfiguration.cs
@@ -1,40 +1,22 @@
-using Microsoft.Extensions.Configuration;
+using System.ComponentModel.DataAnnotations;
namespace Musify.Infrastructure.Configuration
{
+#pragma warning disable CS8618
public class KeycloakConfiguration
{
public const string SectionName = "Keycloak";
- public string BaseUrl { get; set; } = string.Empty;
+ [Required]
+ public string BaseUrl { get; set; }
- public string Realm { get; set; } = string.Empty;
+ [Required]
+ public string Realm { get; set; }
- public string Username { get; set; } = string.Empty;
+ [Required]
+ public string Username { get; set; }
- public string Password { get; set; } = string.Empty;
-
- public static KeycloakConfiguration Load(IConfiguration configuration)
- {
- var keycloakConfiguration = configuration.GetSection(SectionName).Get()
- ?? throw new InvalidOperationException($"{SectionName} configuration section not found.");
-
- Validate(keycloakConfiguration);
- return keycloakConfiguration;
- }
-
- static void Validate(KeycloakConfiguration configuration)
- {
- EnsureValue(configuration.BaseUrl, nameof(configuration.BaseUrl));
- EnsureValue(configuration.Realm, nameof(configuration.Realm));
- EnsureValue(configuration.Username, nameof(configuration.Username));
- EnsureValue(configuration.Password, nameof(configuration.Password));
- }
-
- static void EnsureValue(string value, string name)
- {
- if (string.IsNullOrEmpty(value))
- throw new InvalidOperationException($"{name} configuration value not found.");
- }
+ [Required]
+ public string Password { get; set; }
}
}
\ No newline at end of file
diff --git a/Infrastructure/Identity/KeycloakDependencyInjection.cs b/Infrastructure/Identity/KeycloakDependencyInjection.cs
index 6ff5c3b..af34c25 100644
--- a/Infrastructure/Identity/KeycloakDependencyInjection.cs
+++ b/Infrastructure/Identity/KeycloakDependencyInjection.cs
@@ -10,10 +10,14 @@ namespace Musify.Infrastructure.Identity
{
public static void AddKeycloakAuthentication(this IServiceCollection serviceDescriptors, IConfiguration configuration)
{
- var keycloakConfiguration = KeycloakConfiguration.Load(configuration);
- serviceDescriptors.AddSingleton(keycloakConfiguration);
+ var keycloakConfiguration = serviceDescriptors.AddOptionsWithValidateOnStart()
+ .Bind(configuration)
+ .ValidateDataAnnotations();
+
serviceDescriptors.AddScoped(serviceProvider =>
{
+ var keycloakConfiguration = serviceProvider.GetRequiredService();
+
return new KeycloakClient(
keycloakConfiguration.BaseUrl,
keycloakConfiguration.Username,
diff --git a/Infrastructure/Identity/KeycloakIdentityService.cs b/Infrastructure/Identity/KeycloakIdentityService.cs
index ecb3f13..a2d1d8f 100644
--- a/Infrastructure/Identity/KeycloakIdentityService.cs
+++ b/Infrastructure/Identity/KeycloakIdentityService.cs
@@ -23,15 +23,14 @@ namespace Musify.Infrastructure.Identity
}
catch (OperationCanceledException)
{
- throw;
+ logger.LogError("Operation to retrieve Keycloak user with id {KeycloakId} was cancelled.", keycloakId);
+ return Result.Error("Operation was cancelled.");
}
catch (Exception exception)
{
logger.LogWarning(exception, "Keycloak user with id {KeycloakId} could not be retrieved.", keycloakId);
-
return Result.NotFound();
}
-
return Result.Success(KeycloakUserMapper.Map(keycloakUser));
}