60 lines
3.3 KiB
C#
60 lines
3.3 KiB
C#
using adas_core.Application.Services.Caching;
|
|
using adas_core.Application.Services.Interfaces;
|
|
using adas_core.Domain.Models.AppSettings;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Options;
|
|
|
|
namespace adas_core.Infrastructure.Utils
|
|
{
|
|
/// <summary>
|
|
/// Provides extension methods for configuring or building cache host instances.
|
|
/// </summary>
|
|
/// <!-- aidoc:v1 sig=f280f01 -->
|
|
public static class CacheHostBuilderExtension
|
|
{
|
|
/// <summary>
|
|
/// Registers the cache infrastructure on the host, exposing <see cref="ICacheService"/> through a <see cref="CacheDispatcher"/> that can route to either an in-memory or Redis-backed implementation based on <see cref="CacheSettings"/>. <see cref="RedisService"/> is wired lazily so that its <see cref="RedisService.Database"/> is only resolved once the underlying connection has been established asynchronously, while <see cref="CacheService"/> is provided with an <see cref="InMemoryLockProvider"/> and <see cref="NoCacheService"/> is registered as a no-op fallback.
|
|
/// </summary>
|
|
/// <param name="hostBuilder">The <see cref="IHostBuilder"/> to extend with the cache service registrations.</param>
|
|
/// <returns>The same <paramref name="hostBuilder"/> instance, configured with the cache services for fluent chaining.</returns>
|
|
/// <!-- aidoc:v1 sig=06693b5 body=f80dd06 -->
|
|
public static IHostBuilder UseCache(this IHostBuilder hostBuilder)
|
|
{
|
|
return hostBuilder.ConfigureServices((context, services) =>
|
|
{
|
|
services.Configure<CacheSettings>(context.Configuration.GetSection("CacheSettings"));
|
|
services.AddSingleton(sp => sp.GetRequiredService<IOptions<CacheSettings>>().Value);
|
|
|
|
services.AddSingleton<InMemoryLockProvider>();
|
|
services.AddSingleton<NoCacheService>();
|
|
|
|
// RedisLockProvider obtiene IDatabase de forma lazy a través de una clausura,
|
|
// ya que la conexión se establece de forma asíncrona dentro de RedisService.
|
|
services.AddSingleton<RedisService>(sp => {
|
|
RedisService? svcRef = null;
|
|
var lockProvider = new RedisLockProvider(() => svcRef?.Database);
|
|
var lockMgr = new LockManagerService(
|
|
sp.GetRequiredService<ILogger<LockManagerService>>(),
|
|
lockProvider);
|
|
svcRef = new RedisService(
|
|
sp.GetRequiredService<IOptions<CacheSettings>>(),
|
|
sp.GetRequiredService<ILogger<RedisService>>(),
|
|
lockMgr);
|
|
return svcRef;
|
|
});
|
|
|
|
// Inyectamos LockManager con InMemoryLockProvider
|
|
services.AddSingleton<CacheService>(sp => {
|
|
var lockMgr = new LockManagerService(
|
|
sp.GetRequiredService<ILogger<LockManagerService>>(),
|
|
sp.GetRequiredService<InMemoryLockProvider>());
|
|
return new CacheService(lockMgr);
|
|
});
|
|
|
|
services.AddSingleton<ICacheService, CacheDispatcher>();
|
|
});
|
|
}
|
|
}
|
|
} |