void Close() { if (_fs != null) { if (_root != null) { foreach (var e in _root.Descendants <IDisposable>().Reverse()) { e.Dispose(); } _root = null; } _command.UnregisterAll(keepFilter: _existingCommands.Contains); if (CurrentWorld != null) { CurrentWorld = null; } _fs.Dispose(); _fs = null; } }
public bool Open(IActivityMonitor m, string worldFullNameOr1BasedIndex) { if (!CanOpen) { throw new InvalidOperationException(); } using (m.OpenInfo($"Opening world '{worldFullNameOr1BasedIndex}'.")) { var all = Store.ReadWorlds(m); if (all == null) { return(false); } IRootedWorldName w; if (Int32.TryParse(worldFullNameOr1BasedIndex, out var idx)) { if (idx >= 1 && idx <= all.Count) { w = all[idx - 1]; m.Info($"World '{worldFullNameOr1BasedIndex}' is world {w.FullName}."); } else { m.Error($"Invalid index: {idx} out of {all.Count}."); return(false); } } else { w = all.FirstOrDefault(x => x.FullName.Equals(worldFullNameOr1BasedIndex, StringComparison.OrdinalIgnoreCase)); if (w == null) { m.Error($"Unable to find World {worldFullNameOr1BasedIndex} among {all.Select( x => x.FullName ).Concatenate()}."); return(false); } } Debug.Assert(w != null); Close(); var keySnapshot = _userKeyStore.CreateSnapshot(); var baseProvider = new SimpleServiceContainer(); _fs = new FileSystem(w.Root, _command, _userKeyStore, baseProvider); baseProvider.Add <ISimpleObjectActivator>(new SimpleObjectActivator()); baseProvider.Add(_command); baseProvider.Add(_fs); baseProvider.Add <IWorldName>(w); baseProvider.Add(Store); baseProvider.Add(_appLife); baseProvider.Add(_userKeyStore); var original = Store.ReadWorldDescription(m, w).Root; var expanded = XTypedFactory.PreProcess(m, original); if (expanded.Errors.Count > 0) { return(false); } bool resetSecrets = true; _root = _factory.CreateInstance <XTypedObject>(m, expanded.Result, baseProvider); if (_root != null) { var xW = _root.Descendants <IXTypedObjectProvider <World> >().FirstOrDefault(); if (xW != null) { if (_userKeyStore.Infos.All(secret => !secret.IsRequired || secret.IsSecretAvailable)) { CurrentWorld = xW.GetObject(m); if (CurrentWorld != null) { return(true); } } else { var missing = _userKeyStore.Infos.Where(secret => secret.IsRequired && !secret.IsSecretAvailable).Select(s => s.Name).Concatenate(); m.Error($"Missing one or more secrets. These are required to continue: {missing}."); resetSecrets = false; } } else { m.Error("Missing expected World definition element."); } } if (resetSecrets) { keySnapshot.RestoreTo(_userKeyStore); } Close(); return(false); } }