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; } }
static bool CreateChildren(XTypedObject parent, XTypedObject.Initializer parentConfig) { SimpleServiceContainer cChild = null; List <XTypedObject> created = null; XTypedFactory typeFactory = null; var eParent = parent.XElement; foreach (var child in eParent.Elements()) { if (typeFactory == null) { typeFactory = parentConfig.ChildServices.GetService <XTypedFactory>(true); } var rChild = parentConfig.Reader.WithElement(child, false); var tChild = typeFactory.GetMappping(rChild); if (tChild != null) { if (cChild == null) { cChild = new SimpleServiceContainer(parentConfig.ChildServices); } var config = new XTypedObject.Initializer(parent, rChild, cChild); var o = (XTypedObject)cChild.SimpleObjectCreate(rChild.Monitor, tChild, config); if (created == null) { created = new List <XTypedObject>(); } created.Add(o); if (o == null || !CreateChildren(o, config)) { return(false); } rChild.WarnUnhandledAttributes(); } } return(parent.OnChildrenCreated(parentConfig, (IReadOnlyList <XTypedObject>)created ?? Array.Empty <XTypedObject>())); }
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); } }
/// <summary> /// Constructor for child objects. /// </summary> /// <param name="parent">The parent object. Never null.</param> /// <param name="eReader">The element reader.</param> /// <param name="services">The available services.</param> internal Initializer( XTypedObject parent, in XElementReader eReader,