Files
adas-core/adas-core.Infrastructure/Utils/CacheHostBuilderExtension.cs
T

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>();
});
}
}
}