internal InlineRenameListenerFactory( IVimApplicationSettings vimApplicationSettings, SVsServiceProvider vsServiceProvider) { _vimApplicationSettings = vimApplicationSettings; if (InlineRenameUtil.TryCreate(vsServiceProvider, out IInlineRenameUtil renameUtil)) { RenameUtil = renameUtil; } }
internal static bool TryCreateCore(SVsServiceProvider vsServiceProvider, out InlineRenameUtil InlineRenameUtil) { Type getActiveSessionChangedEventArgsType(string versionNumber) { var typeName = "ActiveSessionChangedEventArgs"; // This type moved between DLLS in newer versions of Visual // Studio. Accept it in any of the locations. var all = new[] { "Microsoft.CodeAnalysis.EditorFeatures", "Microsoft.CodeAnalysis.EditorFeatures.Wpf", }; foreach (var assemblyName in all) { var name = $"Microsoft.CodeAnalysis.Editor.Implementation.InlineRename.InlineRenameService+{typeName}, {assemblyName}, Version={versionNumber}, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; try { var type = Type.GetType(name, throwOnError: false); if (type != null) { return(type); } } catch (Exception) { // There are cases it will throw even though we specified not to throw. } } throw new Exception($"Could not locate {typeName}"); } try { var componentModel = vsServiceProvider.GetService <SComponentModel, IComponentModel>(); var exportProvider = componentModel.DefaultExportProvider; var inlineRenameService = exportProvider.GetExportedValue <object>("Microsoft.CodeAnalysis.Editor.Implementation.InlineRename.InlineRenameService"); var inlineRenameServiceType = inlineRenameService.GetType(); var activeSessionPropertyInfo = inlineRenameServiceType.GetProperty("ActiveSession", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); InlineRenameUtil = new InlineRenameUtil(inlineRenameService, activeSessionPropertyInfo); // Subscribe to the event. var version = GetRoslynVersionNumber(inlineRenameService.GetType().Assembly); var activeSessionChangedEventInfo = inlineRenameServiceType.GetEvent("ActiveSessionChanged", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); var eventArgsTypeArgument = getActiveSessionChangedEventArgsType(version); var openType = typeof(EventHandler <>); var delegateType = openType.MakeGenericType(eventArgsTypeArgument); var methodInfo = InlineRenameUtil.GetType().GetMethod("OnActiveSessionChanged", BindingFlags.Instance | BindingFlags.NonPublic); var delegateInstance = Delegate.CreateDelegate(delegateType, InlineRenameUtil, methodInfo); var addMethodInfo = activeSessionChangedEventInfo.GetAddMethod(nonPublic: true); addMethodInfo.Invoke(inlineRenameService, new[] { delegateInstance }); return(true); } catch (Exception) { // If type load fails that is not a problem. It is expected to // happen in cases where Roslyn is not available InlineRenameUtil = null; return(false); } }