源生成器(三):调试方法及传递引用

序
源生成器(增量生成器)由于它特殊的定位,关于它的调试十分困难。在这里分享一些调试它的经验
另外经常有写类库,然后提供可以生成代码的Attribute给用户的需求,此时需要用到传递引用的知识点
源生成器执行时间
源生成器项目和普通的项目不同
普通的会在你按下运行或调试后才会运行;而源生成器会在两种情况下运行:
重新生成解决方案或该项目时候运行,运行后会生成dll文件。在下一次启动VS的时候,会连着dll一起读取,所以可能会有VS找不到生成的文件导致报错,但可以正常运行的问题,重启VS即可
在生成项目后第二次及以后打开项目时,每次对代码进行更改都会重新运行源生成器的dll,并实时将生成的代码加入到项目中。所以源生成器的执行效率很大程度关乎用户的编程手感
以下程序段默认引用命名空间:
启动调试器
在源生成器项目中,直接在Visual Studio用鼠标点击行号左边打的(红色圆形的)断点是没有用的,需要添加一条Debugger.Launch();,表示启动了调试器
如果程序运行到这条语句时,会弹出一个窗口,选择调试的程序:

建议选择自己的项目(在此图的第二个)即可
点击OK后程序会停在Debugger.Launch();处,此时可以插入Debugger.Break();或直接鼠标点击插入断点
如果要启动调试器,Debugger.Launch();一定要放在源生成器刚开始的位置,而且不要插入多个,尤其不能插在多次执行的程序块内(如循环);若有需要可在其中打断点,否则第二次打开VS会一直弹窗
生成中关闭调试器
有时运行一半时发现问题无需继续调试时,需要关闭调试器。但简单地终止调试可能无效,因为可能遇到另一个Debugger.Launch();
所以我们需要先停止生成,再关闭调试器
生成→取消
(如果调试器没有关闭)调试→停止调试
关闭Visual Studio前
关闭之前我们应该先把Debugger.Launch();删除或注释掉,并重新生成项目,以免下次打开VS的时候自动弹出调试器窗口
类库中分析器的传递引用
从引用项目时的方式就可以看出,生成器项目本身是作为分析器(Analyzer)项目引入的:
此时类库项目引用了源生成器项目,类库项目又被用户项目引用,那么问题是用户项目可以被源生成器生成代码吗?
答案一般是不能
如果要实现这种效果,那需要满足两个条件:
类库项目应作为NuGet包被引用,而非项目引用
类库项目将分析器包含进NuGet包,即:
其中XXX.SourceGenerator.dll是源生成器项目的输出文件路径
注:如果项目没有使用NuGet包的必要,并且可以实现项目引用,又有此类需求;则可以简单地让用户项目按分析器引用源生成器项目即可
引用图片
