using System; using System.Collections.Generic; using EmbedIO.Sessions.Internal; namespace EmbedIO.Sessions { /// /// Provides the same interface as a session object, /// plus a basic interface to a session manager. /// /// /// A session proxy can be used just as if it were a session object. /// A session is automatically created wherever its data are accessed. /// /// public sealed class SessionProxy : ISessionProxy { private readonly IHttpContext _context; private readonly ISessionManager? _sessionManager; private ISession? _session; private bool _onCloseRegistered; internal SessionProxy(IHttpContext context, ISessionManager? sessionManager) { _context = context; _sessionManager = sessionManager; } /// /// Returns a "dummy" interface that will always behave as if no session manager has been defined. /// /// /// The returned interface is only useful /// to initialize a non-nullable property of type . /// public static ISessionProxy None => DummySessionProxy.Instance; /// public bool Exists => _session != null; /// public string Id { get { EnsureSessionExists(); return _session!.Id; } } /// public TimeSpan Duration { get { EnsureSessionExists(); return _session!.Duration; } } /// public DateTime LastActivity { get { EnsureSessionExists(); return _session!.LastActivity; } } /// public int Count => _session?.Count ?? 0; /// public bool IsEmpty => _session?.IsEmpty ?? true; /// public object this[string key] { get { EnsureSessionExists(); return _session![key]; } set { EnsureSessionExists(); _session![key] = value; } } /// public void Delete() { EnsureSessionExists(); if (_session == null) return; _sessionManager!.Delete(_context, _session.Id); _session = null; } /// public void Regenerate() { if (_session != null) _sessionManager!.Delete(_context, _session.Id); EnsureSessionManagerExists(); _session = _sessionManager!.Create(_context); } /// public void Clear() => _session?.Clear(); /// public bool ContainsKey(string key) { EnsureSessionExists(); return _session!.ContainsKey(key); } /// public bool TryGetValue(string key, out object value) { EnsureSessionExists(); return _session!.TryGetValue(key, out value); } /// public bool TryRemove(string key, out object value) { EnsureSessionExists(); return _session!.TryRemove(key, out value); } /// public IReadOnlyList> TakeSnapshot() { EnsureSessionExists(); return _session!.TakeSnapshot(); } private void EnsureSessionManagerExists() { if (_sessionManager == null) throw new InvalidOperationException("No session manager registered in the web server."); } private void EnsureSessionExists() { if (_session != null) return; EnsureSessionManagerExists(); _session = _sessionManager!.Create(_context); if (_onCloseRegistered) return; _context.OnClose(_sessionManager.OnContextClose); _onCloseRegistered = true; } } }