/// <summary> /// Tear down any app domain that currently exists, create a new one and reload the control in /// the given app domain. /// </summary> public async void Reload() { UnloadDomain(); Status = ControlHostStatus.Waiting; if (!File.Exists(_configuration.PathToAssembly)) { // try again in a little bit _timer.Start(); return; } AdditionalInformation = null; Status = ControlHostStatus.Loading; try { // creating an app-domain (and loading everything etc.) takes a while, so do it on a background // thread and resume later. await Task.Run(() => { _lastDomain = AppDomainUtils.CreateShadowAppDomain("Document-Host") .ResolveAssembliesFrom(_rootDictionary); _currentEntryPoint = _lastDomain.CreateInstanceOf <InAppDomainController>() .FindEntryPoint(_assemblyToObserve); }); // dictionaries are serialized (read: copied) instead of passed by reference across app-domains Dictionary <string, string> tempConfiguration; var reference = _currentEntryPoint.Initialize(_configuration.Data, out tempConfiguration); _configuration.Data = tempConfiguration; var proxyElement = FrameworkElementAdapters.ContractToViewAdapter(reference); Host = proxyElement; proxyElement.Loaded += delegate { Keyboard.Focus(proxyElement); TraversalRequest request = new TraversalRequest(FocusNavigationDirection.Next); Host.MoveFocus(request); }; Status = ControlHostStatus.Valid; } catch (Exception exception) { AdditionalInformation = exception.ToString(); UnloadDomain(ignoreShutdown: true); Status = ControlHostStatus.Waiting; } }
/// <summary> Shuts down the current entry point. </summary> private void UnloadDomain(bool ignoreShutdown = false) { if (_lastDomain == null) { return; } if (!ignoreShutdown && _currentEntryPoint != null) { try { _configuration.Data = _currentEntryPoint.Shutdown(_configuration.Data); _currentEntryPoint = null; } catch (Exception) { } } Host = null; AppDomain.Unload(_lastDomain); _lastDomain = null; }