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