我正在实施一个系统,该系统将实现代码质量作为内部质量措施的一部分 . 我用两种可能的实现方式构建了系统,如下所示:
Implementation 1: (Already implemented)
-
AutoUpdate扩展(存根)
-
C#CodeQualityPlugin(Roslyn C#Diagnostic Analyzer&Code Fix)
-
VB CodeQualityPlugin(Roslyn VB诊断分析器和代码修复)
AutoUpdate功能通过验证其版本号来检查自身和其他CodeQuality插件的任何更新 . 一旦更新了CodeQuality插件,它将停止接下来7天的更新 .
这是我目前的实现想法,但是由于此实现中与扩展数量相关的可能性能问题以及可能存在Visual Studio对其使用/性能的限制(如团队所述),因此停止开发
Implementation 2: (Suggested)
-
C#CodeQualityPlugin(Roslyn C#Diagnostic Analyzer,Code Fix,AutoUpdate)
-
VB CodeQualityPlugin(Roslyn VB诊断分析器,代码修复,自动更新)
在此,更新功能被单独触发并保持单一责任理念 .
我不确定AutoUpdate项目(使用菜单命令模板)和C#/ VB CodeFix / DiagnosticAnalyzer项目(Roslyn模板)是否可以共存?
Implementation 3: (One of the opinion)
- CodeQualityPlugin(Roslyn C#/ VB诊断分析器,代码修复,自动更新)
我甚至不确定这三个是否可以在单个vsix中共存 .
所以我的问题可能是上述三种场景中的性能问题,以及我们如何将基于Roslyn模板开发的插件实现为visual studio的普通菜单命令模板扩展 .
---EDIT--- 总结要求如下
-
Coexistence :VSPackage扩展(用于扩展Visual Studio的shell命令组件)和Managed Extensibility Framework / MEF扩展(用于自定义和扩展编辑器以包含Roslyn DiagnosticAnalyzer / CodeFix),应该共存于
-
单VSIX
-
最多2个VSIX
-
Performance :共存不应影响性能,VSPackage扩展所处理的AutoUpdate不应创建冗余服务调用 .
2 回答
没有 .
你可以拥有的唯一真正的“性能问题”是将C#和VB放在同一个程序集中(注意,而不是VSIX),这意味着当我们必须加载一个时,我们加载其他组件 .
从MEF的角度来看,我们只得到一个出口清单:我们不知道它们来自哪个VSIX,而且即使我们想要也很难弄清楚 . 那么你把东西放进去的VSIX根本不重要:根据对你的用户有意义的东西来划分它们 .
Roslyn和VSIX包装的注意事项:
作为mentioned由Srivatsn
引用
Microsoft.CodeAnalysis.CSharp
和Microsoft.CodeAnalysis.VisualBasic
的扩展名将会即使我们尝试打开C#项目,也加载两个编译器,这并不理想 .
如果我们必须分析符号
ISymbolAnalyzer
,在那里只分析符号而不是语法节点,那么我们应该采用一个与语言无关的分析器 . 这意味着我们不必引用任何C#/ VB dll(即使Microsoft正在考虑实现更多与语言无关的分析器) . 包括两个导出属性 - 每种语言一个,这些属性告诉VS实例化并在解决方案中包含相应的语言时调用这些分析器 .编译作为一个进程在编译完成后离开内存,但由于几乎每次击键都会发生编译,如果分析器同时引用c#和VB,它会将两个编译器都带入内存 . 由于存在持久性特征,如果解决方案下存在大型项目,则可能会出现问题(这是我的典型 生产环境 方案)
在调用相应的语法方法时,或者在导出的分析器实例化时(通过提及相应的语言用例再次通过MEF导出属性进行过滤),是否加载编译器存在混淆,因为他还提到了if引用这两种语法节点的方法可能会使JIT编译并加载dll .
链接到菜单命令的任何分析器都是VS特定的,如果它们链接到项目,那么它也将参与构建,甚至在VS之外通过MSBuild
VSIX应该能够导出多个组件以扩展这两个扩展点 .
由mentioned由VSadov
如mentioned由SLaks
由mentioned由Kevin Pilch
虽然这些程序集的打包位置并不重要,除非它们在涉及特定于语言的引用时是独立的 .
如果分析器同时引用C#和VB特定的Roslyn程序集并且这些编译器程序集很大,则将保留虚拟内存
性能问题是磁盘加载和JIT成本(如果没有编译且只有引用,我不确定JIT成本是多少),但由于保留了地址空间,VS中可能存在问题(我不确定这将是一个什么问题 . )
据他所说,微软所做的是创建三个项目来解决这个问题(据Srivatsn称,微软仍在尝试使用与语言无关的分析器)
共享(其中没有特定语言的二进制文件)
C#特定(共享库)
VB特定(共享库)
如果没有引用特定于语言的二进制文件,并且MEF导出是否适当地归因于
ContentType
或LanguageName
那么上述问题可以解决我们可以将其他程序集捆绑到一个VSIX中(通过在其中嵌入其他项目),VS将独立加载每个程序集
最终实施:
所以最后我和我的团队讨论后得出如下结论
通过在其中嵌入以下项目来实现单个VSIX实现
更新插件
检查过去7天是否有更新
然后通过JSON请求检查服务器端插件的版本号
然后从服务器下载插件,将下载日期存储在VS设置中进行初始检查
禁用以前的插件
卸载以前的插件
安装新插件
此功能在触发时触发
VS加载
手动菜单命令(应该覆盖下载日期检查)
C#插件
实现并仅引用C#的规则
VB插件
实现并仅引用VB的规则