예제 #1
0
 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;
     }
 }
예제 #2
0
 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);
     }
 }