adding cache, ICache. RedisOptions and registering services in CLI and web app
This commit is contained in:
parent
222c738854
commit
1714e3f911
@ -9,6 +9,7 @@ namespace Selector.CLI
|
|||||||
config.GetSection(RootOptions.Key).Bind(options);
|
config.GetSection(RootOptions.Key).Bind(options);
|
||||||
config.GetSection(FormatKeys( new[] { RootOptions.Key, WatcherOptions.Key})).Bind(options.WatcherOptions);
|
config.GetSection(FormatKeys( new[] { RootOptions.Key, WatcherOptions.Key})).Bind(options.WatcherOptions);
|
||||||
config.GetSection(FormatKeys( new[] { RootOptions.Key, DatabaseOptions.Key})).Bind(options.DatabaseOptions);
|
config.GetSection(FormatKeys( new[] { RootOptions.Key, DatabaseOptions.Key})).Bind(options.DatabaseOptions);
|
||||||
|
config.GetSection(FormatKeys( new[] { RootOptions.Key, RedisOptions.Key})).Bind(options.RedisOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RootOptions ConfigureOptions(IConfiguration config)
|
public static RootOptions ConfigureOptions(IConfiguration config)
|
||||||
@ -35,6 +36,7 @@ namespace Selector.CLI
|
|||||||
public string ClientSecret { get; set; }
|
public string ClientSecret { get; set; }
|
||||||
public WatcherOptions WatcherOptions { get; set; } = new();
|
public WatcherOptions WatcherOptions { get; set; } = new();
|
||||||
public DatabaseOptions DatabaseOptions { get; set; } = new();
|
public DatabaseOptions DatabaseOptions { get; set; } = new();
|
||||||
|
public RedisOptions RedisOptions { get; set; } = new();
|
||||||
public EqualityChecker Equality { get; set; } = EqualityChecker.Uri;
|
public EqualityChecker Equality { get; set; } = EqualityChecker.Uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,4 +80,12 @@ namespace Selector.CLI
|
|||||||
public bool Enabled { get; set; } = false;
|
public bool Enabled { get; set; } = false;
|
||||||
public string ConnectionString { get; set; }
|
public string ConnectionString { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RedisOptions
|
||||||
|
{
|
||||||
|
public const string Key = "Redis";
|
||||||
|
|
||||||
|
public bool Enabled { get; set; } = false;
|
||||||
|
public string ConnectionString { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using NLog.Extensions.Logging;
|
using NLog.Extensions.Logging;
|
||||||
|
|
||||||
using Selector.Model;
|
using Selector.Model;
|
||||||
|
using Selector.Cache;
|
||||||
|
using StackExchange.Redis;
|
||||||
|
|
||||||
namespace Selector.CLI
|
namespace Selector.CLI
|
||||||
{
|
{
|
||||||
@ -51,6 +53,23 @@ namespace Selector.CLI
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.RedisOptions.Enabled)
|
||||||
|
{
|
||||||
|
Console.WriteLine("> Configuring Redis...");
|
||||||
|
|
||||||
|
if(string.IsNullOrWhiteSpace(config.RedisOptions.ConnectionString))
|
||||||
|
{
|
||||||
|
Console.WriteLine("> No Redis configuration string provided, exiting...");
|
||||||
|
Environment.Exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var connMulti = ConnectionMultiplexer.Connect(config.RedisOptions.ConnectionString);
|
||||||
|
services.AddSingleton(connMulti);
|
||||||
|
services.AddSingleton<IDatabaseAsync>(connMulti.GetDatabase());
|
||||||
|
|
||||||
|
services.AddSingleton<ICache<string>, RedisCache>();
|
||||||
|
}
|
||||||
|
|
||||||
switch (config.Equality)
|
switch (config.Equality)
|
||||||
{
|
{
|
||||||
case EqualityChecker.Uri:
|
case EqualityChecker.Uri:
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
|
||||||
<PackageReference Include="NLog" Version="4.7.11" />
|
<PackageReference Include="NLog" Version="4.7.12" />
|
||||||
<PackageReference Include="NLog.Extensions.Logging" Version="1.7.4" />
|
<PackageReference Include="NLog.Extensions.Logging" Version="1.7.4" />
|
||||||
<PackageReference Include="SpotifyAPI.Web" Version="6.2.2" />
|
<PackageReference Include="SpotifyAPI.Web" Version="6.2.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
24
Selector.Cache/ICache.cs
Normal file
24
Selector.Cache/ICache.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Selector.Cache
|
||||||
|
{
|
||||||
|
public interface ICache<TKey>
|
||||||
|
{
|
||||||
|
public Task<string> Get(TKey key);
|
||||||
|
public Task<bool> Set(TKey key, string value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is this unnecessary?
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <typeparam name="TKey"></typeparam>
|
||||||
|
public interface ICacheSerialiser<T, TKey>
|
||||||
|
{
|
||||||
|
public Task<bool> Write(TKey key, T obj, ICache<TKey> cache);
|
||||||
|
public Task<T> Read(TKey key, ICache<TKey> cache);
|
||||||
|
}
|
||||||
|
}
|
19
Selector.Cache/JsonSerialiser.cs
Normal file
19
Selector.Cache/JsonSerialiser.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using SpotifyAPI.Web;
|
||||||
|
|
||||||
|
namespace Selector.Cache
|
||||||
|
{
|
||||||
|
public static class JsonSerialiser
|
||||||
|
{
|
||||||
|
public static async Task<T> Read<T>(this ICache<string> cache, string key)
|
||||||
|
=> JsonSerializer.Deserialize<T>(await cache.Get(key));
|
||||||
|
|
||||||
|
public static async Task<bool> Write<T>(this ICache<string> cache, string key, T obj)
|
||||||
|
=> await cache.Set(key, JsonSerializer.Serialize(obj));
|
||||||
|
}
|
||||||
|
}
|
15
Selector.Cache/Key.cs
Normal file
15
Selector.Cache/Key.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Selector.Cache
|
||||||
|
{
|
||||||
|
public class Key
|
||||||
|
{
|
||||||
|
public const string CurrentlyPlayingName = "CurrentlyPlaying";
|
||||||
|
|
||||||
|
public static string CurrentlyPlaying(string user) => Namespace(new[] { user, CurrentlyPlayingName });
|
||||||
|
|
||||||
|
public static string Namespace(string[] args) => string.Join(":", args);
|
||||||
|
}
|
||||||
|
}
|
11
Selector.Cache/Model.cs
Normal file
11
Selector.Cache/Model.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Selector.Cache
|
||||||
|
{
|
||||||
|
public class CurrentPlaying
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
25
Selector.Cache/RedisCache.cs
Normal file
25
Selector.Cache/RedisCache.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
using StackExchange.Redis;
|
||||||
|
|
||||||
|
namespace Selector.Cache
|
||||||
|
{
|
||||||
|
public class RedisCache : ICache<string>
|
||||||
|
{
|
||||||
|
private readonly IDatabaseAsync Db;
|
||||||
|
|
||||||
|
public RedisCache(
|
||||||
|
IDatabaseAsync db
|
||||||
|
) {
|
||||||
|
Db = db;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> Get(string key) => (await Db.StringGetAsync(key)).ToString();
|
||||||
|
|
||||||
|
public async Task<bool> Set(string key, string value) => await Db.StringSetAsync(key, value);
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,19 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.1</TargetFramework>
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
<EnableDefaultCompileItems>true</EnableDefaultCompileItems>
|
<EnableDefaultCompileItems>true</EnableDefaultCompileItems>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="StackExchange.Redis" Version="2.2.79" />
|
<PackageReference Include="StackExchange.Redis" Version="2.2.79" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
|
||||||
|
<PackageReference Include="SpotifyAPI.Web" Version="6.2.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Selector\Selector.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="FluentAssertions" Version="6.1.0" />
|
<PackageReference Include="FluentAssertions" Version="6.2.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
|
||||||
<PackageReference Include="Moq" Version="4.16.1" />
|
<PackageReference Include="Moq" Version="4.16.1" />
|
||||||
<PackageReference Include="xunit" Version="2.4.1" />
|
<PackageReference Include="xunit" Version="2.4.1" />
|
||||||
|
@ -3,10 +3,11 @@ using Microsoft.Extensions.Configuration;
|
|||||||
|
|
||||||
namespace Selector.Web
|
namespace Selector.Web
|
||||||
{
|
{
|
||||||
public static class OptionsHelper {
|
static class OptionsHelper {
|
||||||
public static void ConfigureOptions(RootOptions options, IConfiguration config)
|
public static void ConfigureOptions(RootOptions options, IConfiguration config)
|
||||||
{
|
{
|
||||||
config.GetSection(RootOptions.Key).Bind(options);
|
config.GetSection(RootOptions.Key).Bind(options);
|
||||||
|
config.GetSection(FormatKeys(new[] { RootOptions.Key, RedisOptions.Key })).Bind(options.RedisOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RootOptions ConfigureOptions(IConfiguration config)
|
public static RootOptions ConfigureOptions(IConfiguration config)
|
||||||
@ -35,5 +36,16 @@ namespace Selector.Web
|
|||||||
/// Spotify callback for authentication
|
/// Spotify callback for authentication
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string SpotifyCallback { get; set; }
|
public string SpotifyCallback { get; set; }
|
||||||
|
|
||||||
|
public RedisOptions RedisOptions { get; set; } = new();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RedisOptions
|
||||||
|
{
|
||||||
|
public const string Key = "Redis";
|
||||||
|
|
||||||
|
public bool Enabled { get; set; } = false;
|
||||||
|
public string ConnectionString { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.2" />
|
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.2" />
|
||||||
<PackageReference Include="NLog" Version="4.7.11" />
|
<PackageReference Include="NLog" Version="4.7.12" />
|
||||||
<PackageReference Include="NLog.Extensions.Logging" Version="1.7.4" />
|
<PackageReference Include="NLog.Extensions.Logging" Version="1.7.4" />
|
||||||
<PackageReference Include="NLog.Web.AspNetCore" Version="4.14.0" />
|
<PackageReference Include="NLog.Web.AspNetCore" Version="4.14.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -13,8 +13,11 @@ using Microsoft.AspNetCore.Identity;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
using StackExchange.Redis;
|
||||||
|
|
||||||
using Selector.Model;
|
using Selector.Model;
|
||||||
using Selector.Model.Authorisation;
|
using Selector.Model.Authorisation;
|
||||||
|
using Selector.Cache;
|
||||||
|
|
||||||
namespace Selector.Web
|
namespace Selector.Web
|
||||||
{
|
{
|
||||||
@ -34,6 +37,7 @@ namespace Selector.Web
|
|||||||
{
|
{
|
||||||
OptionsHelper.ConfigureOptions(options, Configuration);
|
OptionsHelper.ConfigureOptions(options, Configuration);
|
||||||
});
|
});
|
||||||
|
var config = OptionsHelper.ConfigureOptions(Configuration);
|
||||||
|
|
||||||
services.AddRazorPages().AddRazorRuntimeCompilation();
|
services.AddRazorPages().AddRazorRuntimeCompilation();
|
||||||
services.AddControllers();
|
services.AddControllers();
|
||||||
@ -92,6 +96,23 @@ namespace Selector.Web
|
|||||||
|
|
||||||
services.AddScoped<IAuthorizationHandler, UserIsSelfAuthHandler>();
|
services.AddScoped<IAuthorizationHandler, UserIsSelfAuthHandler>();
|
||||||
services.AddSingleton<IAuthorizationHandler, UserIsAdminAuthHandler>();
|
services.AddSingleton<IAuthorizationHandler, UserIsAdminAuthHandler>();
|
||||||
|
|
||||||
|
if (config.RedisOptions.Enabled)
|
||||||
|
{
|
||||||
|
Console.WriteLine("> Configuring Redis...");
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(config.RedisOptions.ConnectionString))
|
||||||
|
{
|
||||||
|
Console.WriteLine("> No Redis configuration string provided, exiting...");
|
||||||
|
Environment.Exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var connMulti = ConnectionMultiplexer.Connect(config.RedisOptions.ConnectionString);
|
||||||
|
services.AddSingleton(connMulti);
|
||||||
|
services.AddSingleton<IDatabaseAsync>(connMulti.GetDatabase());
|
||||||
|
|
||||||
|
services.AddSingleton<ICache<string>, RedisCache>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
|
Loading…
Reference in New Issue
Block a user