internal void Shadow(string id) { // note: no thread-safety here, because ShadowFs is thread-safe due to the check // on ShadowFileSystemsScope.None - and if None is false then we should be running // in a single thread anyways var virt = Path.Combine(ShadowFsPath, id, _shadowPath); _shadowDir = _hostingEnvironment.MapPathContentRoot(virt); Directory.CreateDirectory(_shadowDir); var tempfs = new PhysicalFileSystem(_ioHelper, _hostingEnvironment, _loggerFactory.CreateLogger <PhysicalFileSystem>(), _shadowDir, _hostingEnvironment.ToAbsolute(virt)); _shadowFileSystem = new ShadowFileSystem(_innerFileSystem, tempfs); }
internal void UnShadow(bool complete) { var shadowFileSystem = _shadowFileSystem; var dir = _shadowDir; _shadowFileSystem = null; _shadowDir = null; try { // this may throw an AggregateException if some of the changes could not be applied if (complete) { shadowFileSystem.Complete(); } } finally { // in any case, cleanup try { Directory.Delete(dir, true); // shadowPath make be path/to/dir, remove each dir = dir.Replace('/', Path.DirectorySeparatorChar); var min = _hostingEnvironment.MapPathContentRoot(ShadowFsPath).Length; var pos = dir.LastIndexOf(Path.DirectorySeparatorChar); while (pos > min) { dir = dir.Substring(0, pos); if (Directory.EnumerateFileSystemEntries(dir).Any() == false) { Directory.Delete(dir, true); } else { break; } pos = dir.LastIndexOf(Path.DirectorySeparatorChar); } } catch { // ugly, isn't it? but if we cannot cleanup, bah, just leave it there } } }