{"id":17510,"date":"2019-02-14T12:39:22","date_gmt":"2019-02-14T12:39:22","guid":{"rendered":"https:\/\/blog.jetbrains.com\/dotnet\/?p=21520"},"modified":"2022-04-21T12:31:12","modified_gmt":"2022-04-21T11:31:12","slug":"writing-plugins-resharper-rider","status":"publish","type":"dotnet","link":"https:\/\/blog.jetbrains.com\/zh-hans\/dotnet\/2019\/02\/14\/writing-plugins-resharper-rider","title":{"rendered":"Writing plugins for ReSharper and Rider"},"content":{"rendered":"<p>JetBrains tools are developed with extensibility being a principal goal. In fact, many new features we ship could also be <i>just plugins<\/i>. However, we realised that specifically the setup experience has been a little entry barrier. If you ever tried to write an IDE extension, we recommend you to try again, because <strong>developing ReSharper and Rider plugins becomes a lot easier!<\/strong><\/p>\n<p>In this blog post, we will guide you through <strong>how to get started<\/strong>, and give you some basic advice on <strong>how to succeed<\/strong> with your plugin ideas.<\/p>\n<p><em>Click bait news: &#8220;I was typing code and then <a href=\"https:\/\/plugins.jetbrains.com\/plugin\/8251-power-mode-ii\" target=\"_blank\" rel=\"noopener\">this<\/a> happened!&#8221;<\/em><\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/01\/dotnet-plugin-repo.png\" alt=\"JetBrains Plugin Repository\" width=\"600\" \/><br \/>\n<!--more--><\/p>\n<h2>Excursion into history<\/h2>\n<p>ReSharper supports plugins since the <a href=\"https:\/\/confluence.jetbrains.com\/display\/NETCOM\/ReSharper+2.5+Plugin+Development\" target=\"_blank\" rel=\"noopener\">early beginnings<\/a>. Some time ago, you would just compile your plugin and put the assemblies into the ReSharper <code>bin<\/code> directory. Or you would pass a <code>\/ReSharper.Plugin<\/code> parameter along with the path to <code>devenv.exe<\/code>.<\/p>\n<p>The easy times have changed a bit, unfortunately. This happened foremost because of the growing ecosystem around our .NET tools &#8211; hello dotPeek, dotTrace, and dotMemory &#8211; but also due to increasing demand for performance optimizations in combination with Visual Studio. And now there is also Rider, as our cross-platform IDE based on IntelliJ IDEA, which also &#8211; kind of &#8211; allows us to load ReSharper plugins if you use some magic involving bits of JVM, Kotlin, and Gradle. Sigh\u2026 Let\u2019s get over the technology bingo!<\/p>\n<h2>One template to rule them all<\/h2>\n<p>We want you to get started quickly with writing plugins in both ReSharper and Rider, and the <a href=\"https:\/\/github.com\/jetbrains\/resharper-rider-plugin\" target=\"_blank\" rel=\"noopener\">resharper-rider-plugin template<\/a> will do just that! It is a Work-In-Progress, so any feedback is welcome. The template can be downloaded from the <a href=\"https:\/\/github.com\/jetbrains\/resharper-rider-plugin\/releases\" target=\"_blank\" rel=\"noopener\">release page<\/a> and <a href=\"https:\/\/github.com\/matkoch\/resharper-sampleplugin#getting-started\" target=\"_blank\" rel=\"noopener\">installed using the dotnet CLI<\/a>.<\/p>\n<p>It is recommended to also use the dotnet CLI for unpacking the template. For instance, call <code>dotnet new resharper-rider-plugin --name AwesomePlugin<\/code>. This will unpack not just a project, but a full solution containing all relevant files for targeting ReSharper <i>and <\/i>Rider:<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/01\/dotnet-solution-explorer.png\" alt=\"All relevant files for developing a ReSharper and Rider plugin\" width=\"325\" \/><\/p>\n<p>The convenience of this template is that it also ships with <a href=\"https:\/\/www.jetbrains.com\/help\/idea\/creating-and-editing-run-debug-configurations.html\" target=\"_blank\" rel=\"noopener\">run configurations<\/a> to <strong>test your plugin with a single click<\/strong>, in either Rider or Visual Studio:<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/01\/dotnet-run-configurations.png\" alt=\"Run configurations for VisualStudio and Rider (Win\/Linux)\" width=\"450\" \/><\/p>\n<p><strong>Rider plugins can have two parts<\/strong>, a ReSharper part dealing with source code (like C# code analysis and refactorings), and an optional Rider part for custom UIs and other IntelliJ platform related features.<\/p>\n<p>These two parts run in separate processes, and can communicate with each other using a custom protocol. The <i>Generate protocol<\/i> run configuration helps to integrate into this protocol easily. A sample <a href=\"https:\/\/www.jetbrains.com\/help\/resharper\/sdk\/Products\/Rider.html#protocol-extension\" target=\"_blank\" rel=\"noopener\">protocol extension<\/a> is pre-generated in the <code>protocol<\/code> directory. You can find more background in the article <a href=\"https:\/\/www.codemag.com\/Article\/1811091\/Building-a-.NET-IDE-with-JetBrains-Rider\" target=\"_blank\" rel=\"noopener\">Building a .NET IDE with JetBrains Rider<\/a> written by Maarten Balliauw and Chris Woodruff.<\/p>\n<p>Now, just try executing one of the Rider or Visual Studio configurations, and your plugin will be shown in an <strong>experimental instance<\/strong>. By default, the template ships with samples for code inspections and quick-fixes. Can you spot what they do?<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/01\/dotnet-debug2.png\" alt=\"Running a Rider plugin in an experimental instance\" width=\"700\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2019\/01\/dotnet-debug2.gif\" \/><\/p>\n<h2>So what can my plugin do?<\/h2>\n<p>As an experienced ReSharper or Rider user, you probably know about common features like code inspections, quick-fixes, or context-actions. Our developer guides for the <a href=\"https:\/\/www.jetbrains.com\/help\/resharper\/sdk\/welcome.html\" target=\"_blank\" rel=\"noopener\">ReSharper SDK<\/a> and the <a href=\"http:\/\/www.jetbrains.org\/intellij\/sdk\/docs\/welcome.html\" target=\"_blank\" rel=\"noopener\">IntelliJ SDK<\/a> are good resources to follow up on more advanced topics.<\/p>\n<p>Nevertheless, the whole platform of ReSharper, Rider, and IDEA is <strong>one big open SDK<\/strong> and pretty much everything is extensible. That also results in the fact that the developer guides will probably never be able to cover all the possibilities.<\/p>\n<p>A <strong>good way for getting inspired<\/strong> is to go straight to the <a href=\"http:\/\/plugins.jetbrains.com\/\" target=\"_blank\" rel=\"noopener\">JetBrains Plugins Repository<\/a> (Rider) or the <a href=\"https:\/\/plugins.jetbrains.com\/resharper\/\" target=\"_blank\" rel=\"noopener\">ReSharper Plugins Repository<\/a> and look at some other plugins. Currently, there are around 50 plugins for ReSharper and 1200 plugins for Rider available. Read again, that number is not a typo!<\/p>\n<p>Many plugins are open-source &#8211; looking at their repositories will give you some more views on how things can be done. Some of the open-source plugins are maintained by JetBrains employees and illustrate how common features are implemented while following best practices. The <a href=\"https:\/\/github.com\/JetBrains\/resharper-unity\" target=\"_blank\" rel=\"noopener\">resharper-unity<\/a> and <a href=\"https:\/\/github.com\/JetBrains\/fsharp-support\" target=\"_blank\" rel=\"noopener\">fsharp-support<\/a> plugins are good resources for a variety of applications.<\/p>\n<h2>Help! I need somebody!<\/h2>\n<p>As already mentioned, covering the entire SDK is almost impossible. So we would like to encourage you to approach us directly if you have questions. We recently started an <strong>internal Slack channel<\/strong> that allows you to get together with us and other developers to exchange ideas, and seek for help. Drop <a href=\"mailto:matthias.koch@jetbrains.com\">me<\/a> a message to get invited.<\/p>\n","protected":false},"author":553,"featured_media":0,"comment_status":"open","ping_status":"open","template":"","categories":[1401],"tags":[],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet\/17510"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/types\/dotnet"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/users\/553"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/comments?post=17510"}],"version-history":[{"count":2,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet\/17510\/revisions"}],"predecessor-version":[{"id":241788,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/dotnet\/17510\/revisions\/241788"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/media?parent=17510"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/categories?post=17510"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/tags?post=17510"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/cross-post-tag?post=17510"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}