ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Rider多项目开发实战:一个窗口管理多个Solution与Project的完整方案

Rider多项目开发实战:一个窗口管理多个Solution与Project的完整方案 很多Rider用户都有过这样的经历手头同时维护着两三个项目或者是公司主项目加上自己的调试用Demo工程这时候如果每次切换都要重新开一个窗口、等一遍索引效率确实很受影响。今天这篇就专门围绕“一个窗口开发两个项目”这个需求把Rider里能用的几种方案从头到尾捋一遍顺便把一些容易踩的坑也一起说清楚。先说结论Rider里要实现“一个窗口管多个项目”其实有两条完全不同的路径取决于你所谓的“项目”到底是什么。如果你说的是.NET解决方案里的Project.csproj那答案很简单——把它们放进同一个Solution就行这是IDE天然支持的用法。如果你说的是两个互不相干的Solution.sln也想塞进同一个窗口那就得动点脑筋了但同样有办法做到。下面挨个拆开讲。1. 先搞清楚一个核心概念Rider眼中的“项目”是什么1.1 Project、Solution和Folder的关系很多刚从Visual Studio转到Rider的人会在这一步被搞混。Rider是基于IntelliJ平台做的它的导航树和VS不完全一样但在处理.NET工程时它遵守的还是.NET世界的规矩一个Solution.sln可以包含多个Project.csproj/.vbproj等每个Project又可以有各自的文件夹结构、依赖关系、构建配置。你可以把Solution理解成一个“总控台”它本身不写业务代码只负责记录装了哪些Project、这些Project之间的编译顺序、启动配置、以及各自的构建条件Debug/Release。Project则是真正承载代码的单元一个Project一般对应一个可输出程序集的项目比如一个webapi服务、一个类库、一个单元测试工程。所以当有人问“怎么在一个窗口开发两个项目”最标准的答案就是建一个Solution把两个Project都放进去。这个方案的好处是两个项目在同一个工程树里一目了然代码跳转、编译顺序、调试断点都无缝衔接你不用来回切换窗口也不用担心跨Solution的引用配不对。1.2 两种常见的真实需求场景在实际开发里想“一个窗口开两个项目”的人通常遇到的是下面两种情况中的一种。第一种是主项目加附属项目的组合。比如你在做一个Web API系统同时需要一个控制台工具来批量造数据或者一个类库来抽公共代码又或者一个测试项目来保证接口质量。这些项目本来是围绕同一个业务在转逻辑上就是一个整体就应该放同一个Solution里。用Rider的Solution视角管理起来项目引用、属性继承、统一构建全部省心。第二种是两个完全独立的业务工程比如你一边在改公司OA系统一边在维护自己的一个开源小工具。它们之间没有任何代码引用甚至可能在两个不同的Git仓库里。这种也想要一个窗口搞定主要动机无非是省内存、省切换时间、方便对照看代码。这种情况就不能硬塞进一个Solution了你得用Rider的多窗口排列或者附加目录功能。搞清楚自己属于哪种后面的操作才不会走冤枉路。2. 最正统的做法一个Solution管理多个Project2.1 从零开始新建Solution并创建多个Project如果你的两个项目未来大概率会互相有依赖或者你希望用同一条构建链路统一管理那别犹豫直接走“一个Solution多个Project”的路线。下面演示一个最常见的组合主项目是一个ASP.NET Core Web API附带一个用于数据处理的控制台工具。在Rider里打开File菜单选择New在弹窗里选择Solution然后填Solution名称选择存放路径。注意Rider默认会让你顺便勾选创建Solution的具体模板实际上你可以先建一个空的Solution再把项目一个个添加进去。用纯空Solution起步能让你的目录结构更干净尤其是当你有多个项目要放进去的时候不会产生一堆align到默认位置的目录。空Solution建好后在Solution Explorer窗口一般在左侧找到Solution节点右键选择Add - New Project然后在模板列表里选择ASP.NET Core Web API。填好项目名称后Rider会默认勾选“Create new Git repository”如果你这整个组合本来就准备放一个仓库里这个可以保留如果每个项目独立仓库建议取消勾选不然后面会多出来一堆submodule问题。第二个项目同理右键Solution节点Add - New Project这次选Console App或Class Library。我建议如果只是工具类的东西选Console App即可如果是供Web API引用的共享代码选Class Library更合适。操作到这一步你的Solution树已经很清晰了MySolution.sln └── src ├── MyApiProject │ └── (Controllers, Models, Program.cs ...) └── MyToolProject └── (Program.cs ...)这里说明一下Rider的Solution Explorer默认会按项目自身的目录结构展示如果你想在Solution上加一层“src”之类的虚拟目录可以在Solution节点上右键Add - Solution Folder然后给不同项目分类归组。这个Solution Folder只是逻辑分组不会影响磁盘上的物理路径纯视觉管理别在这里纠结。2.2 把已经存在的项目塞进同一个Solution现在说第二种更常见的实操场景你手头已经有两个项目了是过去分别创建的目录各自独立现在想让它们在一个Solution里统一管理。这种情况不用重新建项目直接添加现有项目就行。在Rider里右键Solution节点选择Add - Existing Project然后通过文件对话框定位到你要添加的.csproj文件选中确认即可。这个操作不会复制任何代码只是把已有项目的路径登记到Solution文件里。它要求被添加的.csproj文件存在且格式合法一般没什么大坑。不过要提醒一句如果两个项目在磁盘上位于完全不同的目录添加进同一个Solution后它们仍然会在各自路径上编译不会自动合并目录。这个没关系Solution本身不关心物理路径它只记录相对/绝对路径。为了代码可移植性我建议尽量把同一套解决方案的项目文件放在相邻的目录层级里比如都在某个根目录下的不同子文件夹中。这样你把整个目录拷给别人或者换一台电脑Solution还能正常打开。如果你用了绝对路径换环境后大概率要修路径。2.3 Project依赖与引用关系怎么配置两个项目放进同一个Solution之后最大的好处是可以直接添加Project Reference也就是项目间引用。比如你的Web API需要用到另一个类库里的方法右键Web API项目的Dependencies节点选择Add Reference在弹出的窗口里切到Projects选项卡勾选你要引用的项目确认即可。用Project Reference而不是直接引用DLL文件有什么好处最直观的一点是调试时你不需要先手动把类库编译成dll再复制到Web API的bin目录Rider会自动按依赖顺序编译先编被引用的项目再编当前项目。另外断点调试时你能直接跳进被引用项目的源码里走读逻辑比对着反编译代码猜要舒服得多。这里有个实际操作上的建议如果你要引用的项目在同一个Solution里优先用Project Reference如果引用的是外部预编译的dll才用Assembly Reference。两者混着用容易造成版本混乱尤其是当同一个dll既被Project输出覆盖又被手动复制时出现“本地改了代码但运行时不生效”的情况多半就是引用冲突。3. 两个独立Solution想塞进同一个窗口怎么破3.1 最直接的方案两个Rider窗口配合系统的窗口布局如果你的两个项目确实是两个互不相关的Solution强行塞进一个Solution再打开后续隐患挺多的。比如它们各自的依赖版本可能冲突启动配置会互相干扰还有最常遇到的问题——一个Solution里混入了两个本来就独立的Git仓库提交历史会变得乱七八糟。这种情况下我的建议是别折腾了开两个Rider窗口。Jetrains的IDE本身支持多实例你在系统里打开第一个项目后再用File - Open选中第二个SolutionIDE会新开一个窗口把项目展示出来。两个窗口互不干扰各有各的索引、各有各的Run配置。有的人听到“两个窗口”会觉得“这不就又切回老路了吗”其实不然。现在操作系统基本都支持多任务分屏和虚拟桌面比如在Windows上用Win左右方向键快速把两个Rider窗口并排排列在macOS上用Mission Control或者分屏模式效果基本等同于“一个窗口看两个项目”。而且Rider的很多快捷键和编辑器布局是支持跨窗口配置同步的你说它是一个操作空间也没毛病。更重要的是两个窗口的搜索、跳转、版本控制都是独立的切换起来完全隔离不会因为一个项目编译报错而导致另一个项目的状态被污染。这种方案的唯一硬伤就是吃内存。Rider本身是Java系的IDE索引项目后占用几个G的内存是常态。你同时开两个窗口就要准备足够的内存富余。如果你只有16G内存还在跑别的虚拟机那确实会有点吃力。后面我会单独讲怎么优化。3.2 借助Rider自身的窗口排列功能上一小节说的其实是操作系统级别的窗口并排这已经够用了。但Rider本身还提供了一些窗口管理层面的辅助能用好会更顺手。Rider有一个功能叫“Open in Same Window”在File菜单下的Open Recent列表里非常有用。当你打开最近项目时默认会直接新开窗口但如果你在项目名上右键选择“Open in Same Window”它就会复用当前窗口加载项目。这对于“在一个窗口里快速切换两个Solution”来说很关键。具体用法是你先打开Solution A干完一段活儿再从Open Recent里找到Solution B右键选择Open in Same Window当前窗口就会加载Solution B。这相当于省掉了一次关窗口再开窗口的操作至少在切换项目的速度上快了几秒。另外Rider的View菜单里有一些针对当前窗口的工具窗口布局比如可以调整Project工具窗口停靠位置、设置编辑器标签分组。你可以把两个代码文件分别拖到左右两个编辑分组里像写字台左右摊开两本书一样对照看。这个功能对跨项目比对代码非常实用我经常用它同时对比A项目接口实现和B项目调用处的逻辑。操作路径是打开一个项目文件后在编辑器的标签页上右键选择“Move Right”或“Split Right”编辑器区域就会被分割成两个独立窗格你可以在不同窗格里打开不同项目的文件。配合“Open in Same Window”快速切换Solution体验已经非常接近“一个窗口同时管两个项目”了。3.3 进阶方案把外部目录挂进当前工程树假如你不想开两个窗口又想把两个不同仓库的代码放进同一个工程树里浏览Rider其实是支持“附加目录”的。这个功能在IntelliJ系IDE里叫Attach对应到Rider上可以在Project工具窗口里操作。具体做法在当前已打开的Solution的Project工具窗口里找到右上角的齿轮图标或右键菜单看看有没有“Attach Directory”之类的入口。选中你要附加的另一个项目目录后Rider会把它作为一个独立节点挂在当前工程树里可以浏览和编辑里面的代码文件但不会把它的项目结构合并到当前Solution里。这个方案的好处是你可以在同一个窗口里同时看A项目的代码和B项目的代码还能正常搜索、跳转省掉切换和排窗口的麻烦。缺点也很明显B项目不会被当前Solution的编译链路包含也就是说你不能直接在当前窗口对B项目执行编译和调试它更像是一个“代码阅读器”的角色。我个人的看法是这种附加目录的方式适合临时对比代码、或者参考别人的项目实现不适合日常双项目协作开发。如果你真的需要同时开发和调试两个不相关的工程还是回到方案3.1开两个窗口更利索。4. 实战演示一个窗口同时开发Web API和控制台工具4.1 场景规划与目录结构设计下面用一个具体的例子把上面讲的“Solution里多Project”完整走一遍。假设你要做这么一件事写一个ASP.NET Core Web API提供订单查询接口同时需要一个控制台工具定时从某处拉数据并导入数据库。两个项目之间控制台工具需要复用一些时间处理的逻辑所以你还要一个类库项目来放公共代码。目录结构我建议这样规划新建根目录D:\work\OrderSystem在该目录下创建Solution命名OrderSystem.slnSolution下建三个Projectsrc\OrderSystem.ApiWeb APIsrc\OrderSystem.Importer控制台工具src\OrderSystem.Shared公共类库4.2 完整建项流程记录先在Rider里File - New - Solution选择Empty Solution路径选D:\work\OrderSystem命名OrderSystem。然后右键Solution节点Add - New Project模板选ASP.NET Core Web API名称填OrderSystem.Api。注意路径Rider默认可能拼出一个D:\work\OrderSystem\src\OrderSystem.Api\结构如果它没自动建议我建议手动在位置里把src目录加上。这一步能保证你未来不会被一堆平铺的项目文件夹搞乱。再次右键Solution节点Add - New Project模板选Class Library名称填OrderSystem.Shared。这个类库用来放公共代码比如时间格式化、日期范围计算等。第三次右键Solution节点Add - New Project模板选Console App名称填OrderSystem.Importer这个工具将来可以独立运行也可以被手动触发执行导入任务。建完以后给OrderSystem.Api添加对OrderSystem.Shared的项目引用。操作如前面所说右键Api项目的DependenciesAdd Reference勾选Shared确认。同时给OrderSystem.Importer也添加对Shared的引用因为导入工具可能也要用公共时间处理逻辑。4.3 多项目启动配置与调试技巧三个项目都进Solution后怎么运行如果只想运行Web API直接在Rider右上角的运行配置下拉框里选择OrderSystem.Api点运行即可。如果你想同时启动两个项目比如开发Web API时也需要跑着控制台工具那就得用的Rider的组合运行配置了。在Rider右上角运行配置下拉框里选择Edit Configurations然后点左上角的加号新建一个Compound类型的配置。在Compound配置里把OrderSystem.Api和OrderSystem.Importer都勾选上。之后你只要运行这个Compound配置两个项目就会一起启动它们的输出窗口会在Run工具窗口里以不同标签页并列显示。调试也是一样的道理如果你以Compound配置启动调试两个项目都可以断点命中。不过要注意控制台工具如果是那种一启动就执行完就退出的程序设置断点会显得很鸡肋所以实际双启动调试时通常还会给控制台工具加上一个“等待输入/循环执行”的逻辑让进程保持存活才方便观察。这里分享一个经验别让控制台项目在Debug模式下一闪而过导致断点设了也白设。你可以在Main函数第一行加个Console.ReadLine()或者在循环里挂个Thread.Sleep让进程挂住然后再挂断点调试。5. 多项目开发中的常见问题与避坑经验5.1 项目引用与编译顺序常见坑多项目开发时编译顺序最容易出问题。虽然Rider会自动根据Project Reference确定编译顺序但如果你用了项目间“隐式引用”或者文件链接就可能出现“编译时找不到依赖程序集”的诡异问题。一个常见场景你在Api项目的代码里直接using了另一个类库里的命名空间但忘记在Dependencies里添加Project Reference。代码写的时候IDE会提示你缺引用有的人嫌烦就直接把类库编译出来的dll拷到了Api的bin目录里临时解决问题。这种做法短期能编过但一旦类库代码更新Api这边还抱着旧dll运行时不报错调试时却永远走不到新逻辑。代码看起来改了但白改。所以遇到跨项目调用第一选择永远是在IDE里添加Project Reference。如果你发现两个项目不在同一个Solution里实在没法添加Project Reference那就老老实实走NuGet本地包或者多窗口方案别用复制dll这条路。5.2 换机器或拉代码后索引错乱的修复办法多项目解决方案往往比较大换一台电脑或者从Git拉下新代码后Rider的索引有时候会出现状态异常。表现为代码明明不报错编辑器里却满屏红波浪线或者智能提示突然不工作了更恶心的是明明重新编译通过了IDE还是提示找不到某某类型。遇到这种情况第一招是让Rider重新加载项目。右键Solution节点选择Reload Solution。这个操作会触发重新读取sln和csproj文件很多时候索引错乱是因为项目文件在本地被修改过IDE没反应过来。如果Reload不行可以试试File - Invalidate Caches / Restart。它会让你重启IDE并清空本地缓存和索引数据。重启后Rider会自动重新索引项目虽然耗时几分钟但基本能解决绝大多数“提示错乱”问题。我个人习惯是每次拉完新的代码分支尤其是涉及项目文件或包引用变化时随手做一次Reload Solution能省掉后续很多莫名其妙的问题。5.3 老机器同时跑多个Rider项目太卡的优化建议多窗口方案确实是效率神器但前提是硬件带得动。如果你打开两个Rider窗口感觉风扇起飞、鼠标飘移那可以用下面几条实测有效的优化方案。第一关掉不需要的插件。Rider预装了各种框架支持和Unity、游戏开发等插件你用不到的就在Settings - Plugins里禁用掉。插件每少一个后台索引和文件监听的负担就小一分。第二在Settings - Build, Execution, Deployment里把Build Process堆内存调低一点避免两个窗口同时编译时内存挤爆。默认值一般偏大对于多窗口场景把每个窗口的编译堆内存限制在1.5G左右是合理的。第三善用Power Save Mode。在File菜单里可以打开Power Save Mode它会暂时禁掉代码分析、自动检查这些高CPU开销的功能只保留基础的编辑和跳转。阅读代码或者临时改点东西时切到这个模式体感会好很多。缺点是编译器错误提示不会实时刷新不过你真正编译时还是会显示的不影响判断。第四如果只是偶尔需要同时看第二个项目的代码尽量避免再开一个完整窗口改用文本编辑器打开关键文件或者用Rider的远程开发功能连到另一台机器上跑重活。5.4 多项目场景问题速查表场景推荐做法不推荐做法两个项目有公共代码逻辑共用一个Solution添加Project Reference复制dll到bin目录两个项目完全独立但都频繁修改开两个Rider窗口用系统分屏强行塞进一个Solution只想临时对比另一项目的代码Attach目录或直接文件打开开完整窗口占用内存一个Solution里项目太多找不到入口用Solution Folder分类把所有项目平铺在根节点需要同时启动多个项目调试配置Compound运行配置手动一个一个启动再挨个附调试器写在最后的一点体会关于Rider多项目开发这件事我个人的体会是不要为了“合”而合也不要为了“分”而分。同一个业务域里能互相关联的两个项目放进同一个Solution是最省心的两个八竿子打不着的独立系统强行往一个窗口里塞最终只会让索引更慢、调试更乱。真正舒服的工作方式是让工具的用法匹配项目的真实结构该合并的合并该拆开的拆开Rider本身给了足够的灵活度就看你怎么选。另外再补一个小技巧如果你经常在几个Solution之间切换可以把常用方案固定到Open Recent的上方位置。Rider支持对最近项目做收藏右键项目名选择Pin就能固定。这样一来无论你开了几个窗口、切过多少个项目入口永远一眼就能找到。这个操作对提升多项目开发效率的帮助远比想象中要大。
返回列表