using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace Bit.Core.Services; /// /// Singleton wrapper service that bridges singleton-scoped service boundaries for PlayId tracking. /// This allows singleton services to access the scoped PlayIdService via HttpContext.RequestServices. /// /// Uses IHttpContextAccessor to retrieve the current request's scoped PlayIdService instance, enabling /// singleton services to participate in Play session tracking without violating DI lifetime rules. /// Falls back to NeverPlayIdServices when no HttpContext is available (e.g., background jobs). /// public class PlayIdSingletonService(IHttpContextAccessor httpContextAccessor, IHostEnvironment hostEnvironment) : IPlayIdService { private IPlayIdService Current { get { var httpContext = httpContextAccessor.HttpContext; if (httpContext == null) { return new NeverPlayIdServices(); } return httpContext.RequestServices.GetRequiredService(); } } public string? PlayId { get => Current.PlayId; set => Current.PlayId = value; } public bool InPlay(out string playId) { if (hostEnvironment.IsDevelopment()) { return Current.InPlay(out playId); } else { playId = string.Empty; return false; } } }