public Task AttachForCustomMessageAsync(JsonRpc rpc) { _rpc = rpc; // This is a workaround until we have proper API from ILanguageClient for now. _rpc.AllowModificationWhileListening = true; _rpc.CancellationStrategy = new CustomCancellationStrategy(_server.CancellationFolderName, _rpc); _rpc.AllowModificationWhileListening = false; // Create our listener for file events _fileListener = new FileWatcher.Listener(_rpc, WorkspaceService, Site); _disposables.Add(_fileListener); // We also need to switch the order on handlers for all of the rpc targets. Until // the VSSDK gives us a way to do this, use reflection. try { var fi = rpc.GetType().GetField("rpcTargetInfo", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); if (fi != null) { var rpcTargetInfo = fi.GetValue(rpc); if (rpcTargetInfo != null) { fi = rpcTargetInfo.GetType().GetField("targetRequestMethodToClrMethodMap", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); if (fi != null) { // Have to use reflection all the way down as the type of the entry is private var dictionary = fi.GetValue(rpcTargetInfo); var method = dictionary?.GetType().GetMethod("get_Keys"); var keys = method?.Invoke(dictionary, new object[0]) as IEnumerable <string>; foreach (var key in keys) { method = dictionary?.GetType().GetMethod("get_Item"); var list = method?.Invoke(dictionary, new object[1] { key }); var reverse = list?.GetType().GetMethod( "Reverse", BindingFlags.Public | BindingFlags.Instance, null, CallingConventions.Any, new Type[] { }, null); reverse?.Invoke(list, new object[0]); } } } } } catch { // Any exceptions, just skip this part } return(Task.CompletedTask); }