分析器/源生成器添加项目依赖的方式

这篇具有很好参考价值的文章主要介绍了分析器/源生成器添加项目依赖的方式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

title: 分析器/源生成器添加项目依赖的方式
date: 2024-01-20
categories: 编程
tags:
- C#
- .NET
- Roslyn

前言

写分析器(源生成器)时经常需要引用别的包,但直接引用是无法运行的。
下面我们分不同情况来讨论在分析器项目如何对依赖进行引用。

下图中“包引用”指PackageReference,“项目引用”指ProjectReference

其中项目引用是通过dll文件传递的,包引用是通过nupkg文件传递的,
最大的区别是项目引用默认不可以传递,而包引用默认可以传递。

flowchart TD A1--项目引用-->A2 GA--包引用-->A3 GB1--包引用-->B2 GB1-.包引用.->B3 GB2--包引用-->B3 C1--项目引用-->C2 subgraph G1[单NuGet包项目] subgraph GA[NuGet包] direction TB A1[分析器项目] A2[NuGet包主项目] end A3[用户项目] end subgraph G2[NuGet包传递] subgraph GB1[分析器NuGet包] B1[分析器项目] end subgraph GB2[NuGet包] B2[NuGet包项目] end B3[用户项目] end subgraph G3[直接项目引用] C1[分析器项目] C2[用户项目] end

注:首先需要确保引用的包支持.NET Standard 2.0。

直接项目引用

在很多时候只需要写一个特化的源生成器供项目使用时,会使用直接项目引用的方式。
此时我们将需要引用的dll路径告诉分析器即可。

在csproj项目文件中用以下语句[1]即可实现这个功能(以System.Text.Json为例):

<ItemGroup>
    <PackageReference Include="System.Text.Json" Version="8.0.1" GeneratePathProperty="true" PrivateAssets="all" ReferenceOutputAssembly="false" />
</ItemGroup>

<PropertyGroup>
    <GetTargetPathDependsOn>$(GetTargetPathDependsOn);GetDependencyTargetPaths</GetTargetPathDependsOn>
</PropertyGroup>

<Target Name="GetDependencyTargetPaths">
    <ItemGroup>
        <TargetPathWithTargetPlatformMoniker Include="$(PkgSystem_Text_Json)\lib\netstandard2.0\*.dll" IncludeRuntimeDependency="false" />
    </ItemGroup>
</Target>

第一部分ItemGroup是引用包项目。其中:

  • PrivateAssets指定了这个依赖不会传递给用户项目,如果需要传递的话,则无需指定这句;

  • ReferenceOutputAssembly是是否引用这个包,例如“NuGet包传递”模式中,也许只有分析器项目才需要使用这个包,NuGet包主项目并不需要它,即可指定这个属性;

  • GeneratePathProperty是生成PkgSystem_Text_Json属性,我们可以用$(PkgSystem_Text_Json)的方法去获取这个包的dll所在路径,规律是Pkg+包名,其中包名中的替换为下划线

第二部分PropertyGroup是指定需要GetDependencyTargetPaths这个Target

第三部分Target指定了GetDependencyTargetPaths具体如何实现,即将告诉编译器指定dll的路径。

NuGet打包

但由于获取的dll路径是绝对路径,在生成项目时就已经决定了。
NuGet包绝大多数情况都和生成包的设备环境不同,此时上一个方法就失效了。

此时我们可以将需要的dll项目打包进nupkg中:

这个功能(以System.Text.Json为例):

<ItemGroup>
    <PackageReference Include="System.Text.Json" Version="8.0.1" GeneratePathProperty="true" PrivateAssets="all" ReferenceOutputAssembly="false" />
    <None
        Include="$(PkgSystem_Text_Json)\lib\netstandard2.0\System.Text.Json.dll"
        Pack="true"
        PackagePath="analyzers\dotnet\cs\System.Text.Json.dll"
        Visible="false"
        CopyToOutputDirectory="PreserveNewest"/>
</ItemGroup>

一个解决方案有很多项目,那上面的问题应该写在哪呢?有一个很容易的判断标准:

写在用户项目引用的对象上。

举例来说“NuGet包传递”中,NuGet包项目引用了分析器项目的nupkg后传递给了用户项目,本质上引用的是分析器项目(因为用户项目也可以直接引用分析器项目NuGet包),所以我们应该写在分析器的csproj中。

“单NuGet包项目”中,NuGet包主项目会将分析器项目的dll包含进输出的nupkg中,所以我们应该写在NuGet包主项目的csproj中。

但这种方法会导致nupkg包变大,如果大家有更好的方法可以教我噢【


  1. GitHub Disscussion ↩︎文章来源地址https://www.toymoban.com/news/detail-807277.html

到了这里,关于分析器/源生成器添加项目依赖的方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Elasticsearch 查询分析器简介

    Elasticsearch 是一个开源的分布式搜索和分析引擎,它提供了强大的查询和分析功能。它基于 Apache Lucene 构建,支持大规模数据的实时搜索,并具有高可用性和可扩展性。 在 Elasticsearch 中,查询分析器负责处理用户搜索的输入,将文本进行分词并生成倒排索引。分析器在搜索过

    2024年02月17日
    浏览(43)
  • Elasticsearch 文本分析器(下)

    注意:字符过滤器用于在将字符流传递给分词器之前对其进行预处理 此过滤器会替换掉HTML标签,且会转换HTML实体 如: 会被替换为 。 解析结果: 因为是 p 标签,所以有前后的换行符。如果使用span标签就不会有换行符了。 可配参数说明 escaped_tags (可选,字符串数组)不包

    2024年02月08日
    浏览(123)
  • ElasticSearch 基础(七)之分析器

    就 ES 基础部分来说这暂时就是最后一篇的文章,写完之后就会学习 MQ 了。本篇内容简单了解 ES 的分析器,最重要的还是根据自己需求去定制自定义分析器,自定义分析器自行了解,这里只是基础。其他比较重要的就是中文分词器了,只需要知道常用的几种中文分词器就可以

    2024年02月09日
    浏览(42)
  • Elasticsearch:搜索及索引分析器

    在我之前的文章 “Elasticsearch: analyzer”,我详细介绍了在 Elasticsearch 中的分析器。分析器在 Elasticsearh 中,它在索引文档的时候需要使用,同时,它也在搜索时,也需要针对搜索的文字进行分词。在今天的文章中,我们来详细介绍分析器是如何在索引及搜索时使用的。 可以在

    2024年02月05日
    浏览(84)
  • 词法分析器的设计与实现

    1.1、实验目的         加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分析。 1.2、实验要求         1)对单词的构词规则有明确的定义;      

    2024年02月13日
    浏览(53)
  • Android Profiler 内存分析器使用

    Android Profiler是Android Studio的一部分,提供了一个集成的性能分析工具套件,包括内存分析。Android Profiler 工具可提供实时数据,帮助您了解应用的 CPU、内存、网络和电池资源使用情况。 在Android Profiler中,您可以查看内存使用情况的实时图表、堆转储快照、分析内存泄漏等,

    2024年02月08日
    浏览(53)
  • 编译原理-6-LR语法分析器

    自顶向下的、不断归约的、基于句柄识别自动机的、适用于LR(∗) 文法的、LR(∗) 语法分析器 只考虑无二义性的文法 自底向上 构建语法分析树 根节点 是文法的起始符号 S S S 每个中间 非终结符节点 表示 使用它的某条产生式进行归约 叶节点 是词法单元$w$$ 仅包含终结符号与

    2024年02月05日
    浏览(48)
  • 编译原理实验三:预测分析法语法分析器的设计

    ​ 根据文法编制预测分析法语法分析程序,以便对输入的符号串进行语法分析。通过编写预测分析法语法分析程序掌握预测分析法的基本原理、FIRST和FOLLOW集的计算、预测分析表的构造方法以及语法分析法主控程序的设计。 对于给定的上下文无关文法,编程完成以下功能:

    2024年02月05日
    浏览(55)
  • 编译原理词法分析器(C/C++)

            词法分析器不用多说,一开始我还不知道是什么样的,看了下别人的博客,再看看书,原来是输出二元组,这不就是字符串操作嘛。然后细看几篇博客,发现大都是用暴力判断来写的。我对代码重复性比较高的方法不太感冒,不是说我编程有多好,就是单纯的不喜欢

    2024年02月06日
    浏览(60)
  • 【编译原理】 实验一:词法分析器的自动实现(Lex词法分析)

    相关代码实操移步视频 https://www.bilibili.com/video/BV13x4y1o7FL 1.借助词法分析工具Flex或Lex完成(参考网络资源) 2.输入:高级语言源代码(如helloworld.c) 3.输出:以二元组表示的单词符号序列。 通过设计、编制、调试一个具体的词法分析程序,加深对词法分析原理的理解,并掌握

    2024年02月08日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包