// initializes a new scope private Scope(ScopeProvider scopeProvider, ILogger logger, FileSystems fileSystems, Scope parent, ScopeContext scopeContext, bool detachable, IsolationLevel isolationLevel = IsolationLevel.Unspecified, RepositoryCacheMode repositoryCacheMode = RepositoryCacheMode.Unspecified, IEventDispatcher eventDispatcher = null, bool?scopeFileSystems = null, bool callContext = false, bool autoComplete = false) { _scopeProvider = scopeProvider; _logger = logger; Context = scopeContext; _isolationLevel = isolationLevel; _repositoryCacheMode = repositoryCacheMode; _eventDispatcher = eventDispatcher; _scopeFileSystem = scopeFileSystems; _callContext = callContext; _autoComplete = autoComplete; Detachable = detachable; #if DEBUG_SCOPES _scopeProvider.RegisterScope(this); Console.WriteLine("create " + InstanceId.ToString("N").Substring(0, 8)); #endif if (detachable) { if (parent != null) { throw new ArgumentException("Cannot set parent on detachable scope.", nameof(parent)); } if (scopeContext != null) { throw new ArgumentException("Cannot set context on detachable scope.", nameof(scopeContext)); } if (autoComplete) { throw new ArgumentException("Cannot auto-complete a detachable scope.", nameof(autoComplete)); } // detachable creates its own scope context Context = new ScopeContext(); // see note below if (scopeFileSystems == true) { _fscope = fileSystems.Shadow(); } return; } if (parent != null) { ParentScope = parent; // cannot specify a different mode! // TODO: means that it's OK to go from L2 to None for reading purposes, but writing would be BAD! // this is for XmlStore that wants to bypass caches when rebuilding XML (same for NuCache) if (repositoryCacheMode != RepositoryCacheMode.Unspecified && parent.RepositoryCacheMode > repositoryCacheMode) { throw new ArgumentException($"Value '{repositoryCacheMode}' cannot be lower than parent value '{parent.RepositoryCacheMode}'.", nameof(repositoryCacheMode)); } // cannot specify a dispatcher! if (_eventDispatcher != null) { throw new ArgumentException("Value cannot be specified on nested scope.", nameof(eventDispatcher)); } // cannot specify a different fs scope! // can be 'true' only on outer scope (and false does not make much sense) if (scopeFileSystems != null && parent._scopeFileSystem != scopeFileSystems) { throw new ArgumentException($"Value '{scopeFileSystems.Value}' be different from parent value '{parent._scopeFileSystem}'.", nameof(scopeFileSystems)); } } else { // the FS scope cannot be "on demand" like the rest, because we would need to hook into // every scoped FS to trigger the creation of shadow FS "on demand", and that would be // pretty pointless since if scopeFileSystems is true, we *know* we want to shadow if (scopeFileSystems == true) { _fscope = fileSystems.Shadow(); } } }