/// <summary>
        /// Creates new storage filled from <see cref="ISessionManagerConfiguration"/>.
        /// </summary>
        /// <param name="memoryCache">Memory cache to use.</param>
        /// <param name="configuration">Configuration ro use.</param>
        /// <returns>MemoryCacheStorage instance.</returns>
        public static MemoryCacheStorage <TSessionState, TOperationState> CreateFromSettings(
            IMemoryCache memoryCache,
            ISessionManagerConfiguration configuration)
        {
            string sectionName = $"OperationManager{configuration.Id}";

            return(new MemoryCacheStorage <TSessionState, TOperationState>(
                       memoryCache: memoryCache,
                       cacheSectionName: sectionName,
                       configureCacheEntry: cacheContext =>
            {
                cacheContext.CacheEntry.AbsoluteExpirationRelativeToNow = configuration.SessionCacheTimeToLive;
            }));
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="SessionManager{TSessionState, TOperationState}"/> class.
        /// </summary>
        /// <param name="configuration">Configuration.</param>
        /// <param name="loggerFactory">Logger factory.</param>
        /// <param name="sessionStorage">Session storage.</param>
        /// <param name="initServices">Initializes <see cref="Services"/> that can be used in operation managers.</param>
        /// <param name="metadata">Optional metadata.</param>
        public SessionManager(
            ISessionManagerConfiguration configuration,
            ILoggerFactory loggerFactory,
            ISessionStorage <TSessionState, TOperationState> sessionStorage,
            Action <IServiceContainer>?initServices = null,
            IPropertyContainer?metadata             = null)
        {
            Configuration  = configuration.AssertArgumentNotNull(nameof(configuration));
            LoggerFactory  = loggerFactory.AssertArgumentNotNull(nameof(loggerFactory));
            SessionStorage = sessionStorage.AssertArgumentNotNull(nameof(sessionStorage));

            _metadata = new MutablePropertyContainer(sourceValues: metadata);

            var serviceContainer = new ServiceContainer();

            serviceContainer.AddService(typeof(ILoggerFactory), LoggerFactory);
            initServices?.Invoke(serviceContainer);
            Services = serviceContainer;

            GlobalLock = new SemaphoreSlim(configuration.MaxConcurrencyLevel);
            _metadata.SetValue(SessionMetricsMeta.GlobalConcurrencyLevel, configuration.MaxConcurrencyLevel);
        }