<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Dapr .NET SDK 最佳实践 on Dapr 文档库</title><link>https://docs.dapr.io/zh-hans/developing-applications/sdks/dotnet/dotnet-guidance/</link><description>Recent content in Dapr .NET SDK 最佳实践 on Dapr 文档库</description><generator>Hugo</generator><language>zh-hans</language><atom:link href="https://docs.dapr.io/zh-hans/developing-applications/sdks/dotnet/dotnet-guidance/index.xml" rel="self" type="application/rss+xml"/><item><title>Dapr .NET SDK 中的错误模型</title><link>https://docs.dapr.io/zh-hans/developing-applications/sdks/dotnet/dotnet-guidance/dotnet-guidance-error-model/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://docs.dapr.io/zh-hans/developing-applications/sdks/dotnet/dotnet-guidance/dotnet-guidance-error-model/</guid><description>&lt;p>Dapr .NET SDK 支持 Dapr 运行时实现的更丰富的错误模型。该模型为应用程序提供了一种使用额外上下文来丰富错误的方式，
使应用程序的使用者能够更好地理解问题并更快地解决它。您可以在&lt;a href="https://google.aip.dev/193">这里&lt;/a>阅读有关更丰富的错误模型的更多信息，并可以在&lt;a href="https://github.com/googleapis/googleapis/blob/master/google/rpc/error_details.proto">这里&lt;/a>找到实现这些错误的 Dapr proto 文件。&lt;/p>
&lt;p>Dapr .NET SDK 实现了 Dapr 运行时支持的所有详细信息，在 &lt;code>Dapr.Common.Exceptions&lt;/code> 命名空间中实现，并通过
&lt;code>DaprException&lt;/code> 扩展方法 &lt;code>TryGetExtendedErrorInfo&lt;/code> 访问。目前，此详细信息提取仅支持存在详细信息的
&lt;code>RpcException&lt;/code>。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">// ExtendedErrorInfo 的使用示例&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">try&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8f5902;font-style:italic">// 使用 Dapr 客户端执行某些会抛出 DaprException 的操作。&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">catch&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">DaprException&lt;/span> &lt;span style="color:#000">daprEx&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">if&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">daprEx&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">TryGetExtendedErrorInfo&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#204a87;font-weight:bold">out&lt;/span> &lt;span style="color:#000">DaprExtendedErrorInfo&lt;/span> &lt;span style="color:#000">errorInfo&lt;/span>&lt;span style="color:#000;font-weight:bold">))&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Console&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">WriteLine&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">errorInfo&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Code&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Console&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">WriteLine&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">errorInfo&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Message&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">foreach&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">DaprExtendedErrorDetail&lt;/span> &lt;span style="color:#000">detail&lt;/span> &lt;span style="color:#204a87;font-weight:bold">in&lt;/span> &lt;span style="color:#000">errorInfo&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Details&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Console&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">WriteLine&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">detail&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">ErrorType&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">switch&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">detail&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">ErrorType&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">case&lt;/span> &lt;span style="color:#000">ExtendedErrorType&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">ErrorInfo&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Console&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">WriteLine&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">detail&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Reason&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Console&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">WriteLine&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">detail&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Domain&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">break&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">default&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">Console&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">WriteLine&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">detail&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">TypeUrl&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">break&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="daprextendederrorinfo">DaprExtendedErrorInfo&lt;/h2>
&lt;p>包含与错误关联的 &lt;code>Code&lt;/code>（状态代码）和 &lt;code>Message&lt;/code>（错误消息），从内部的 &lt;code>RpcException&lt;/code> 解析而来。
还包含从异常的详细信息中解析的 &lt;code>DaprExtendedErrorDetails&lt;/code> 集合。&lt;/p>
&lt;h2 id="daprextendederrordetail">DaprExtendedErrorDetail&lt;/h2>
&lt;p>所有详细信息都实现抽象的 &lt;code>DaprExtendedErrorDetail&lt;/code> 并具有关联的 &lt;code>DaprExtendedErrorType&lt;/code>。&lt;/p></description></item><item><title>Experimental Attributes</title><link>https://docs.dapr.io/zh-hans/developing-applications/sdks/dotnet/dotnet-guidance/dotnet-guidance-experimental-attributes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://docs.dapr.io/zh-hans/developing-applications/sdks/dotnet/dotnet-guidance/dotnet-guidance-experimental-attributes/</guid><description>&lt;h2 id="experimental-attributes">Experimental Attributes&lt;/h2>
&lt;h3 id="experimental-attributes-简介">Experimental Attributes 简介&lt;/h3>
&lt;p>随着 .NET 8 的发布，C# 12 引入了 &lt;code>[Experimental]&lt;/code> 属性，它提供了一种标准化的方式来标记仍在开发或实验阶段的 API。该属性定义在 &lt;code>System.Diagnostics.CodeAnalysis&lt;/code> 命名空间中，需要一个诊断 ID 参数，用于在使用实验性 API 时生成编译器警告。&lt;/p>
&lt;p>在 Dapr .NET SDK 中，我们现在使用 &lt;code>[Experimental]&lt;/code> 属性而不是 &lt;code>[Obsolete]&lt;/code> 来标记尚未通过稳定生命周期认证的构建块和组件。这种方法提供了更清晰的区分：&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>Experimental APIs&lt;/strong> — 已经可用但仍在演进的功能，尚未根据 &lt;a href="https://docs.dapr.io/operations/components/certification-lifecycle/">Dapr Component Certification Lifecycle&lt;/a> 认证为稳定。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Obsolete APIs&lt;/strong> — 真正已被弃用并将在未来版本中移除的功能。&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h3 id="在-dapr-net-sdk-中的使用">在 Dapr .NET SDK 中的使用&lt;/h3>
&lt;p>在 Dapr .NET SDK 中，我们在类级别为仍处于 &lt;a href="https://docs.dapr.io/operations/components/certification-lifecycle/">Component Certification Lifecycle&lt;/a> 的 Alpha 或 Beta 阶段的构建块应用 &lt;code>[Experimental]&lt;/code> 属性。该属性包括：&lt;/p>
&lt;ul>
&lt;li>一个用于标识实验性构建块的诊断 ID&lt;/li>
&lt;li>一个指向该构建块相关文档的 URL&lt;/li>
&lt;/ul>
&lt;p>例如：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">using&lt;/span> &lt;span style="color:#000">System.Diagnostics.CodeAnalysis&lt;/span>&lt;span style="color:#000;font-weight:bold">;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">namespace&lt;/span> &lt;span style="color:#000">Dapr.Cryptography.Encryption&lt;/span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">{&lt;/span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#c4a000"> [Experimental(&amp;#34;DAPR_CRYPTOGRAPHY&amp;#34;, UrlFormat = &amp;#34;https://docs.dapr.io/developing-applications/building-blocks/cryptography/cryptography-overview/&amp;#34;)]&lt;/span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#204a87;font-weight:bold">public&lt;/span> &lt;span style="color:#204a87;font-weight:bold">class&lt;/span> &lt;span style="color:#000">DaprEncryptionClient&lt;/span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">{&lt;/span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#8f5902;font-style:italic">// Implementation &lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">}&lt;/span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>诊断 ID 遵循 &lt;code>DAPR_[BUILDING_BLOCK_NAME]&lt;/code> 的命名约定，例如：&lt;/p></description></item><item><title>Integration testing with Dapr.Testcontainers</title><link>https://docs.dapr.io/zh-hans/developing-applications/sdks/dotnet/dotnet-guidance/dotnet-guidance-testcontainers/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://docs.dapr.io/zh-hans/developing-applications/sdks/dotnet/dotnet-guidance/dotnet-guidance-testcontainers/</guid><description>&lt;h2 id="概述">概述&lt;/h2>
&lt;p>&lt;code>Dapr.Testcontainers&lt;/code> 是一个辅助包，用于使用容器针对真实的 Dapr 运行时组件编写集成测试。它封装了 &lt;code>Testcontainers&lt;/code> 库来启动 Dapr 边车、控制平面服务（placement 和 scheduler）以及特定 Dapr 构建块所需的基础设施。&lt;/p>


&lt;div class="alert alert-warning" role="alert">
&lt;h4 class="alert-heading">重要&lt;/h4>

 &lt;code>Dapr.Testcontainers&lt;/code> 是初始版本。API 仍在演进中，可能在未来的版本中发生变化。我们尽量保持变化最小，但在该包成熟的过程中，你应预期可能出现破坏性变更。

&lt;/div>

&lt;h2 id="包">包&lt;/h2>
&lt;ul>
&lt;li>&lt;code>Dapr.Testcontainers&lt;/code>（核心 harness 和基础设施）&lt;/li>
&lt;li>&lt;code>Dapr.Testcontainers.Xunit&lt;/code>（可选的 xUnit 辅助工具）&lt;/li>
&lt;/ul>
&lt;h2 id="前置条件">前置条件&lt;/h2>
&lt;ul>
&lt;li>一个容器运行时（Docker Desktop、Podman 或等效工具）。&lt;/li>
&lt;li>能够拉取 Dapr 和依赖镜像的网络访问。&lt;/li>
&lt;/ul>
&lt;h2 id="核心概念">核心概念&lt;/h2>
&lt;p>&lt;code>Dapr.Testcontainers&lt;/code> 围绕&lt;strong>环境&lt;/strong>和&lt;strong>harness&lt;/strong>来建模测试：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>&lt;code>DaprTestEnvironment&lt;/code>&lt;/strong>：共享基础设施（网络、placement、scheduler、可选 Redis）。当你需要多个应用共享 Dapr 控制平面或运行多应用测试时使用它。&lt;/li>
&lt;li>&lt;strong>&lt;code>DaprHarnessBuilder&lt;/code>&lt;/strong>：为特定构建块（工作流、作业、分布式锁或对话）创建 harness。&lt;/li>
&lt;li>&lt;strong>&lt;code>DaprTestApplicationBuilder&lt;/code>&lt;/strong>：使用 harness 启动你的测试应用，并将 Dapr 端点连接到配置。&lt;/li>
&lt;/ul>
&lt;h2 id="基本工作流测试示例">基本工作流测试示例&lt;/h2>
&lt;p>下面的示例反映了 .NET SDK 测试套件中的工作流集成测试，展示了典型设置：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">var&lt;/span> &lt;span style="color:#000">componentsDir&lt;/span> &lt;span style="color:#000;font-weight:bold">=&lt;/span> &lt;span style="color:#000">TestDirectoryManager&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">CreateTestDirectory&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#4e9a06">&amp;#34;workflow-components&amp;#34;&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">await&lt;/span> &lt;span style="color:#204a87;font-weight:bold">using&lt;/span> &lt;span style="color:#000">var&lt;/span> &lt;span style="color:#000">environment&lt;/span> &lt;span style="color:#000;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">await&lt;/span> &lt;span style="color:#000">DaprTestEnvironment&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">CreateWithPooledNetworkAsync&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">needsActorState&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span> &lt;span style="color:#204a87;font-weight:bold">true&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">await&lt;/span> &lt;span style="color:#000">environment&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">StartAsync&lt;/span>&lt;span style="color:#000;font-weight:bold">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">var&lt;/span> &lt;span style="color:#000">harness&lt;/span> &lt;span style="color:#000;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">new&lt;/span> &lt;span style="color:#000">DaprHarnessBuilder&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">componentsDir&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">WithEnvironment&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">environment&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">BuildWorkflow&lt;/span>&lt;span style="color:#000;font-weight:bold">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">await&lt;/span> &lt;span style="color:#204a87;font-weight:bold">using&lt;/span> &lt;span style="color:#000">var&lt;/span> &lt;span style="color:#000">testApp&lt;/span> &lt;span style="color:#000;font-weight:bold">=&lt;/span> &lt;span style="color:#204a87;font-weight:bold">await&lt;/span> &lt;span style="color:#000">DaprHarnessBuilder&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">ForHarness&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">harness&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">ConfigureServices&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">builder&lt;/span> &lt;span style="color:#000;font-weight:bold">=&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">builder&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">Services&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">AddDaprWorkflowBuilder&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">opt&lt;/span> &lt;span style="color:#000;font-weight:bold">=&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000">opt&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">RegisterWorkflow&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#000">TestWorkflow&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">});&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">})&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">BuildAndStartAsync&lt;/span>&lt;span style="color:#000;font-weight:bold">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">using&lt;/span> &lt;span style="color:#000">var&lt;/span> &lt;span style="color:#000">scope&lt;/span> &lt;span style="color:#000;font-weight:bold">=&lt;/span> &lt;span style="color:#000">testApp&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">CreateScope&lt;/span>&lt;span style="color:#000;font-weight:bold">();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">var&lt;/span> &lt;span style="color:#000">workflowClient&lt;/span> &lt;span style="color:#000;font-weight:bold">=&lt;/span> &lt;span style="color:#000">scope&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">ServiceProvider&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">GetRequiredService&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;lt;&lt;/span>&lt;span style="color:#000">DaprWorkflowClient&lt;/span>&lt;span style="color:#000;font-weight:bold">&amp;gt;();&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">await&lt;/span> &lt;span style="color:#000">workflowClient&lt;/span>&lt;span style="color:#000;font-weight:bold">.&lt;/span>&lt;span style="color:#000">ScheduleNewWorkflowAsync&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">nameof&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">TestWorkflow&lt;/span>&lt;span style="color:#000;font-weight:bold">),&lt;/span> &lt;span style="color:#000">input&lt;/span>&lt;span style="color:#000;font-weight:bold">:&lt;/span> &lt;span style="color:#0000cf;font-weight:bold">42&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="配置-dapr-运行时">配置 Dapr 运行时&lt;/h2>
&lt;p>&lt;code>DaprRuntimeOptions&lt;/code> 让你控制 Dapr 镜像版本、App ID、日志级别和容器日志：&lt;/p></description></item><item><title>Dapr 源代码分析器和生成器</title><link>https://docs.dapr.io/zh-hans/developing-applications/sdks/dotnet/dotnet-guidance/dotnet-guidance-source-generators/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://docs.dapr.io/zh-hans/developing-applications/sdks/dotnet/dotnet-guidance/dotnet-guidance-source-generators/</guid><description>&lt;p>Dapr 支持日益丰富的可选 Roslyn 分析器和代码修复提供程序，用于检查代码中的代码质量问题。从 v1.16 版本开始，开发者可以在每个标准功能包的基础上，从 NuGet 安装额外的项目，从而在解决方案中启用这些分析器。&lt;/p>


&lt;div class="alert alert-primary" role="alert">
&lt;h4 class="alert-heading">Note&lt;/h4>

 Dapr .NET SDK 的未来版本将默认包含这些分析器，无需单独安装包。

&lt;/div>

&lt;p>规则违规通常标记为 &lt;code>Info&lt;/code> 或 &lt;code>Warning&lt;/code>，因此如果分析器发现问题，不一定会中断构建。所有代码分析违规都带有前缀 &amp;ldquo;DAPR&amp;rdquo;，并通过该前缀后的数字进行唯一区分。&lt;/p>


&lt;div class="alert alert-primary" role="alert">
&lt;h4 class="alert-heading">Note&lt;/h4>

 目前，诊断标识符的前两位数字与不同的 Dapr 包一一对应，但随着更多分析器的开发，这一映射方式未来可能会发生变化。

&lt;/div>

&lt;h2 id="安装和配置分析器">安装和配置分析器&lt;/h2>
&lt;p>在 v1.16 Dapr 版本发布后，以下包将可通过 NuGet 获取：&lt;/p>
&lt;ul>
&lt;li>Dapr.Actors.Analyzers&lt;/li>
&lt;li>Dapr.Jobs.Analyzers&lt;/li>
&lt;li>Dapr.Workflow.Analyzers&lt;/li>
&lt;/ul>
&lt;p>在您希望运行分析器的每个项目中安装每个 NuGet 包。该包将作为项目依赖项安装，分析器将在您编写代码时或作为 CI/CD 构建的一部分运行。分析器会标记现有代码中的问题，并在构建项目时警告您新出现的问题。&lt;/p>
&lt;p>我们的许多分析器都有关联的代码修复，可以自动纠正问题。如果您的 IDE 支持此功能，任何可用的代码修复都将作为代码中的内联菜单选项显示。&lt;/p>
&lt;p>此外，我们的大多数分析器还应该报告代码中被识别为规则关键方面的特定语法所在的行号和列号。如果您的 IDE 支持，双击任何分析器警告应该直接跳转到违反分析器规则的代码部分。&lt;/p>
&lt;h3 id="抑制特定分析器">抑制特定分析器&lt;/h3>
&lt;p>如果您希望阻止分析器对项目的某个特定部分进行检查，可以通过多种方式单独抑制其输出。有关在项目或文件中抑制分析器的更多信息，请阅读相关的 &lt;a href="https://learn.microsoft.com/dotnet/fundamentals/code-analysis/suppress-warnings#use-the-suppressmessageattribute">.NET 文档&lt;/a>。&lt;/p>
&lt;h3 id="禁用所有分析器">禁用所有分析器&lt;/h3>
&lt;p>如果您希望在不移除任何提供分析器的包的情况下禁用项目中的所有分析器，请在 csproj 文件中将 &lt;code>EnableNETAnalyzers&lt;/code> 属性设置为 &lt;code>false&lt;/code>。&lt;/p>
&lt;h2 id="可用的分析器">可用的分析器&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>诊断 ID&lt;/th>
 &lt;th>Dapr 包&lt;/th>
 &lt;th>类别&lt;/th>
 &lt;th>严重性&lt;/th>
 &lt;th>添加版本&lt;/th>
 &lt;th>描述&lt;/th>
 &lt;th>可用代码修复&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>DAPR1301&lt;/td>
 &lt;td>Dapr.Workflow&lt;/td>
 &lt;td>Usage&lt;/td>
 &lt;td>Warning&lt;/td>
 &lt;td>1.16&lt;/td>
 &lt;td>工作流类型未向依赖注入提供程序注册&lt;/td>
 &lt;td>Yes&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DAPR1302&lt;/td>
 &lt;td>Dapr.Workflow&lt;/td>
 &lt;td>Usage&lt;/td>
 &lt;td>Warning&lt;/td>
 &lt;td>1.16&lt;/td>
 &lt;td>工作流活动类型未向依赖注入提供程序注册&lt;/td>
 &lt;td>Yes&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DAPR1401&lt;/td>
 &lt;td>Dapr.Actors&lt;/td>
 &lt;td>Usage&lt;/td>
 &lt;td>Warning&lt;/td>
 &lt;td>1.16&lt;/td>
 &lt;td>Actor 计时器方法调用要求在类型上存在指定的回调方法&lt;/td>
 &lt;td>No&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DAPR1402&lt;/td>
 &lt;td>Dapr.Actors&lt;/td>
 &lt;td>Usage&lt;/td>
 &lt;td>Warning&lt;/td>
 &lt;td>1.16&lt;/td>
 &lt;td>Actor 类型未向依赖注入注册&lt;/td>
 &lt;td>Yes&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DAPR1403&lt;/td>
 &lt;td>Dapr.Actors&lt;/td>
 &lt;td>Interoperability&lt;/td>
 &lt;td>Info&lt;/td>
 &lt;td>1.16&lt;/td>
 &lt;td>将 options.UseJsonSerialization 设置为 true 以支持与非 .NET actor 的互操作性&lt;/td>
 &lt;td>Yes&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DAPR1404&lt;/td>
 &lt;td>Dapr.Actors&lt;/td>
 &lt;td>Usage&lt;/td>
 &lt;td>Warning&lt;/td>
 &lt;td>1.16&lt;/td>
 &lt;td>调用 app.MapActorsHandlers 以映射 Dapr actor 的端点&lt;/td>
 &lt;td>Yes&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DAPR1501&lt;/td>
 &lt;td>Dapr.Jobs&lt;/td>
 &lt;td>Usage&lt;/td>
 &lt;td>Warning&lt;/td>
 &lt;td>1.16&lt;/td>
 &lt;td>Job 调用要求为 IEndpointRouteBuilder 上每个预期的作业设置和配置 MapDaprScheduledJobHandler&lt;/td>
 &lt;td>No&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="分析器类别">分析器类别&lt;/h2>
&lt;p>以下是分析器可以分配到的各个有效类别，这些类别是按照 .NET 分析器使用的标准类别建模的：&lt;/p></description></item></channel></rss>