Compare commits

...

248 Commits

Author SHA1 Message Date
Whit Waldo 6b49bed7f1
Re-enabled the test with a fix to use a fixed 30 days for @monthly in actor deserialization for now (#1530)
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2025-05-02 17:35:08 -05:00
Whit Waldo faeeb8eaca
Fix for large file cryptography support (#1528)
* Porting the changes from Dapr.Cryptography 1.16 back to 1.15

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2025-05-02 16:51:41 -05:00
Whit Waldo 0873c5ef6f
Updating gRPC and Microsoft.DurableTask.* packages (#1523)
* Updating gRPC, Google.Protobuf and Microsoft.DurableTask.* packages
2025-04-25 14:45:24 -05:00
Whit Waldo 32d06a7136
Tentative fix for timers deserializing error (#1512)
* Tentative fix for deserializing error
* Added unit tests to prove out timer deserialization for all supported formats

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2025-04-08 00:17:49 -05:00
Whit Waldo 6f07643280
Refactored to make deserialization for GetJobAsync testable. Added unit test to validate reported customer issue. (#1497)
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2025-04-01 17:32:17 -05:00
Whit Waldo 55895fa19d
Updated Dapr runtime/CLI version used in integration tests (#1485)
* Updated itests.yml to use latest 1.15 runtime and CLI versions over 1.14 versions
* Updated CLI argument name as `dapr-http-max-request-size` was changed in a recent update included in the CLI

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2025-03-16 20:14:32 -05:00
Whit Waldo c14fcea0d4
Actor reminder deserialization bugfix (#1483)
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2025-03-11 13:47:17 -05:00
Whit Waldo bb47132f98
Fixed options passed to conversation API without "conversationId" throwing (#1480)
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2025-03-04 11:41:05 -06:00
Whit Waldo cb065f2089
Fixed unit tests validating actor reminder deserialization
Updated unit tests for actor reminder deserialization
2025-02-26 07:09:27 -06:00
Whit Waldo 19fd40390b
Fix: Actor reminders should return null if not registered
Added more checks to determine if a reminder was returned or not having discovered that the runtime returns a 200 even if there's no reminder registered. (#1476)
2025-02-26 06:33:52 -06:00
Whit Waldo 94dcdfd5b2
Actor reminders should return null if not registered (#1468)
* The implementation didn't check the status code for whether the actor reminder request failed or not. This updates it to return null if the reminder isn't present.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed spelling error in unit test name

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit tests to validate GetReminderAsync request

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to reflect changed interface

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit test to validate null response coming through from mocked ActorTimerManager

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated tests throughout class to use `const string` instead of `var` for constants

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit tests to prove out previously implemented reminder retrieval

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2025-02-26 03:54:03 -06:00
Whit Waldo c94b61e0d6
Fix for Jobs mapping handler (#1474)
Tweaked the jobs mapping handler to accept an optional timeout parameter instead of a cancellation token. This applies the timeout, if specified, to each invocation instead of as a global timeout.

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2025-02-26 03:40:58 -06:00
Whit Waldo 52f0851780
Removed out-of-date workflow reference in docs (#1463)
Docs: Removed out-of-date workflow reference
2025-02-24 12:38:47 -06:00
Whit Waldo 2b288a1135
Updating Conversation SDK (#1469)
FIX: Updated conversation protos and types to reflect property change from `message` to `content`

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2025-02-24 11:46:34 -06:00
Whit Waldo 0dc268f501
Fix: Duration-based scheduling is properly formed (#1462)
Fixed: Duration-based scheduling should be properly formatted

When using a duration-based schedule value (e.g. "5s", it's important that the value be preceded by "@every " so it's properly evaluated by the runtime. While a value of "5s" is perfectly valid in the `dueTime` property, the scheduler expects either a Cron expression or a prefixed duration value, necessitating this change.

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2025-02-20 01:14:13 -06:00
Whit Waldo e9ee4d21bf
Fix for `GetJobAsync` deserialization issue (#1461)
Bugfix: `GetJobAsync` deserialization failure

Updated GetJobsAsync deserialization to reflect actual values returned

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2025-02-19 13:07:32 -06:00
Whit Waldo 89d9d56bd5
Fixed Jobs SDK bugs (#1456)
fix: Point-in-time not getting scheduled, job payload not being property set on job invocation

When setting a single point-in-time job, the SDK was incorrectly assigning it as a schedule which would promptly fail cron validation. Rather, this now properly sets it to `dueTime` instead. Further, when a Job is invoked, only the payload it was registered with is provided in the callback, not all the elements of a Get Job response, so this was modified to return the `ReadOnlyMemory<byte>` originally provided in the payload back to the caller.

Reviewed by: @philliphoff
Refs: #1455 #1457
2025-02-11 01:16:35 -06:00
Whit Waldo ab3ef305f2
DurableTask package dependency update (#1452)
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2025-02-03 12:47:05 -06:00
Whit Waldo 9e0672525e
Removed unused reference to FluentAssertions in light of licensing change (#1449)
* Removed unused reference to FluidAssertions in light of licensing change

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed from Dapr.AI.Test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Migrated Dapr.Extensions.Configuration.Test to use Shouldly

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Migrated Dapr.Common.Test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Migrated Dapr.Actors.AspNetCore.Test from FluentAssertions

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing copyright header

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Migrated Dapr.Actors.Test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Migrated Dapr.Client.Test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unused using reference

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Migrated Dapr.E2E.Test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Migrated Dapr.AspNetCore.Test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Migrated Dapr.AspNetCore.IntegrationTest

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed reference to FluentAssertions

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed several unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed another unit test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed more tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed additional unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updating more unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed more unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed more unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed more unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2025-01-30 12:41:06 -06:00
Whit Waldo 676c0d7a7f
Bugfix: Crypto ReadOnlyMemory<byte> decryption times out (#1443)
* Bugfix: Removed use of MemoryMarshal as it wasn't decrypting in-memory byte arrays properly (doesn't impact stream encryption/decryption).

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added extension method similar to how the CommunityToolkit.HighPerformance project handles the creation of MemoryStreams without an allocation. Restored the use of MemoryMarshal, but throws an exception if the data cannot be accessed now, instead of hanging as it did in a previous iteration.

Tested both paths (string and stream) from example project successfully.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing using

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2025-01-15 11:11:26 -06:00
Whit Waldo ef54d75f70
Simplfying Crypto example (#1442)
* Fixed bad console output showing encrypted bytes

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Simplified example so it doesn't require an Azure Key Vault instance and just uses a local set of keys

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated README to include instructions for generating the private key

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added private RSA key to project for users that lack OpenSSL on their system - updated README to include warning calling out that this key shouldn't be used for anything but demonstration and testing purposes.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2025-01-14 17:38:28 -06:00
Hannah Hunter 01b4833474
fix typo (#1439)
Signed-off-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com>
2025-01-08 16:01:00 -06:00
Siri Varma Vegiraju 8b9f932c06
Provide the ability to Mock WorkflowActivityContext (#1358)
* Make context mockable

Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Fix project

Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Consolidated version of coverlet.msbuild, coverlet.collector, xunit, xunit.runner.visualstudio, Microsoft.AspNetCore.Mvc.Testing, Moq to the same version in all projects.

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Make context mockable

Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Fix project

Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Added unit test to prove out concern raised on Discord

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Removed unused using

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Added unit test to validate that headers aren't being stripped off request

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Fixed spelling typo

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Added fix to handle null return values

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Removed unnecessary null check

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Removed deprecated methods from DaprClient and tests as well as unused types

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Removed unused (and invalid) reference

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Removed E2E workflow test as it validated DaprClient and the functionality has been moved out to the Dapr.Workflow project instead.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Adding instance-based CreateInvokableHttpClient (#1319)

This PR takes the implementation of the static method and puts it into the DaprClient instance, pulling from the existing apiTokenHeader on the instance to populate the daprApiToken, pulling the endpoint from the instance's httpEndpoint value and accepting only an appId argument so as to specify the ID of the Dapr app to connect to and place in the resulting URI.

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Fixed security advisory updates across dependencies (transitive and direct) (#1366)

Migrating whole solution to Central Package Management - several package version upgrades to address security advisories and otherwise.

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Removes floating classes and introduces Dapr.Common project (#1365)

Extracting classes out to common project

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Extracted Protos out to common project (#1367)

Protos pulled out to separate shared project

Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Improvement of the dotnet-contributing files (#1330)

Add link about Dapr bot to contribution documentation

Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Support case insensitive cloudevent payloads and forward cloudevent props s headers (#1153)

* forward cloudevent props
Signed-off-by: Ilias Politsopoulos <polil91@hotmail.com>

* refactor middleware
Signed-off-by: Ilias Politsopoulos <polil91@hotmail.com>

* add cloud event property filters
Signed-off-by: Ilias Politsopoulos <polil91@hotmail.com>

* update string check
Signed-off-by: Ilias Politsopoulos <polil91@hotmail.com>

* forward cloudevent props
Signed-off-by: Ilias Politsopoulos <polil91@hotmail.com>

* refactor middleware
Signed-off-by: Ilias Politsopoulos <polil91@hotmail.com>

* add cloud event property filters
Signed-off-by: Ilias Politsopoulos <polil91@hotmail.com>

* update checks
Signed-off-by: Ilias Politsopoulos <polil91@hotmail.com>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Co-authored-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Updating actor serialization documentation (#1371)

* Changed headers, updated introduction to reflect the difference in serialization between either type and added a brief section to detail the use of System.Text.Json for weakly-typed Dapr actor clients and to point to official documentation on it

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Prioritize retrieval of environment variables from IConfiguration instead of directly (#1363)

* Implemented against Dapr.Client.AspNetCore and Dapr.Client

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* SImplified DaprWorkflow DI registration and updated to use IConfiguration preference. Needs testing.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing copyright header

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated actor registration to prefer the updated IConfiguration-based approach for pulling the HTTP endpoint and API token

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Adopted accepted proposal's guidelines for favoring different environment variables for determining the sidecar endpoint. Added notes to explain this in the code going forward.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Made some lines a little more concise, added hostname default to DaprDefaults to use when building endpoints.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed and updated unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to put endpoint resolution mechanism in DaprDefaults within Dapr.Common  - updating projects and unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated packages to fix security advisory https://github.com/advisories/GHSA-447r-wph3-92pm

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated Workflow builder to use DaprDefaults with IConfiguration

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updating global.json

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Tweaked global.json comment

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Adding braces per nit

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Consolidated both registration extension methods to remove duplication

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* cleanup: Removed Serilog nuget from Directory.Packages.props (#1376)

* Removed Serilog nuget from Directory.Packages.props

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Update Directory.Packages.props

Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>

---------

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>
Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Removed sample folder (#1375)

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>
Co-authored-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Remove unused variables (#1314)

* Remove unused variables

Signed-off-by: Rafael Camara <rafaelcamarac@gmail.com>
Signed-off-by: Rafael Câmara <52082556+RafaelJCamara@users.noreply.github.com>
Co-authored-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Remove unused using statements. (#1313)

Signed-off-by: Rafael Camara <rafaelcamarac@gmail.com>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Incremental source generator for actors (#1334)

* Samples - Add k8s deployment yaml to DemoActor sample (#1308)

* up

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed build

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added scripts for image build

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added readme Build and push Docker image

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added demo-actor.yaml

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed typo

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated guide, fixed invocation throw curl

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Removed dockerfile, updated readme, removed ps1 and sh scripts

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated base image

Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Update demo-actor.yaml

Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added overload for DaprClient DI registration (#1289)

* Added overload for DaprClient DI registration allowing the consumer to easily use values from injected services (e.g. IConfiguration).

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added supporting unit test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Co-authored-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Merge `release-1.13` back into `master` (#1285)

* Update protos and related use for Dapr 1.13. (#1236)

* Update protos and related use.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Update Dapr runtime version.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Init properties.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

---------

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Update artifact action versions. (#1240)

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Make recursive true as default (#1243)

Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>

* Fix for secret key transformation in multi-value scenarios (#1274)

* Add repro test.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Fix for secret key transformation in multi-value scenarios.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

---------

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Update Dapr version numbers used during testing.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

---------

Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>
Co-authored-by: Shivam Kumar <shivamkm07@gmail.com>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

---------

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>
Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>
Co-authored-by: Whit Waldo <whit.waldo@innovian.net>
Co-authored-by: Phillip Hoff <phillip@orst.edu>
Co-authored-by: Shivam Kumar <shivamkm07@gmail.com>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Aligned nuget version

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* UP

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* UP

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Debug profile added

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated implementation

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Emitted DAPR001 Diagnostic warning

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added DAPR002 diagnostic

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Cleaun

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* UP

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added summaries

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added base interface to ActorClient

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added ctor

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added nullable directive

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added null check for actorproxy ctor parameter

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Moved DiagnoticException in a dedicate cs file

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Moved generator costants to dedicated class

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added ActorReference creation from the ActorBase class informations (#1277)

* Handled creation of ActorReference from Actor base class

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated null check

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added unit test for GetActorReference from null actore and actor proxy

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added test for ActorReference created inside Actor implementation

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated description

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed test method naming

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added unit test for exception generated in case the type is not convertible to an ActorReference

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

---------

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added overload to support SDK supplying query string on invoked URL (#1310)

* Refactored extensions and their tests into separate directories

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added overload to method invocation to allow query string parameters to be passed in via the SDK instead of being uncermoniously added to the end of the produced HttpRequestMessage URI

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit tests to support implementation

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Marking HttpExtensions as internal to prevent external usage and updating to work against Uri instead of HttpRequestMessage.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated unit tests to match new extension purpose

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Resolved an ambiguous method invocation wherein it was taking the query string and passing it as the payload for a request. Removed the offending method and reworked the remaining configurations so there's no API impact.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed actorProxy argument null check

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Moved ActorClientDesciptor into separta cs file

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Moved textual templates to dedicated class

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated comments, property names

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added argument null check to SyntaxFactoryHelpers

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added comments

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Removed obsolete testing packages https://github.com/dotnet/roslyn-sdk/blob/main/src/Microsoft.CodeAnalysis.Testing/README.md#obsolete-packages

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Adapted existing unit test to new source generated code

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Up

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added tests for SyntaxFactoryHelpers

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated generation of ArgumentNullException

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated nullability

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed internal methods tests

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added test to IEnumerableExtensions

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Unittested GetSyntaxKinds from Accessibility

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* UP

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated assignment implementation of ctor body

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Improved unit test

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added implementation of method generation

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed ArgumentNullException invocation

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added test for NameOfExpression

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed ActorProxy method invocation

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Simplified proxy argument definition

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Explicit generic arguments of the proxy call during generation

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Handled cancellation token with default value

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed typo

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Configured eol used in NormalizeWhitespace function

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Normalized expected source

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Moved to constat the ActorProxyTypeName

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fix typo

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Created ActorProxyInvokeMethodAsync SyntaxFactoryHelper

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Removed custom concat implementation

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* fix (#1329)

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* link to non-dapr endpoint howto (#1335)

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Merge 1.14 release branch back into `master`. (#1337)

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed merge errors
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated some summaries

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added some missing summaries

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed typo

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Improved some summary text

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Improved summaries

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Handled review requests

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Changed SyntaxFactoryHelpers accessor to internal

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

---------

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>
Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>
Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
Co-authored-by: Whit Waldo <whit.waldo@innovian.net>
Co-authored-by: Phillip Hoff <phillip@orst.edu>
Co-authored-by: Shivam Kumar <shivamkm07@gmail.com>
Co-authored-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Add .NET client for Dapr Jobs API (#1384)

* Package addition + updates

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added Dapr.Jobs project

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Initial commit - unable to proceed without update on master from streaming sub PR

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added class to Dapr.Common, fixed compilation errors

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit tests for Dapr.Common enum extensions

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing copyright header

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added sample Jobs project

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added documentation

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing copyright header

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Downgraded Roslyn packages since master doesn't yet have the incremental source generator updates

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Missed a reference regarding incremental source generators

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Downgraded packages to fix nullability issues on build

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Downgraded from 8.* packages back to 6.* packages for the various Microsoft.Extensions.* packages to fix build issues

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unnecessary assignment

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added braces for clarity

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added more curley braces

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* More curly braces again

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Marked two properties as static

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to handle any order of parameters to endpoint route builder delegate

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated default cancellation token value

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing package version in Directory.Packages

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added test to ensure that even if cancellation token is provided, it'll handle the mapping properly

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Updated prereqs to specify .NET 6 and .NET 8 in v1.15 (#1398)

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Refactor DaprWorkflowClientBuilderFactory and WorkflowRuntimeOptions (#1244)

This commit refactors the DaprWorkflowClientBuilderFactory and WorkflowRuntimeOptions classes.

In DaprWorkflowClientBuilderFactory:
- Added a new method, UseGrpcChannelOptions, to allow the use of custom GrpcChannelOptions for creating the GrpcChannel.
- Updated the UseGrpc method to use the GrpcChannelOptions provided by the WorkflowRuntimeOptions.

In WorkflowRuntimeOptions:
- Added a new property, GrpcChannelOptions, to store the custom GrpcChannelOptions.
- Added a new method, UseGrpcChannelOptions, to set the GrpcChannelOptions.

These changes improve the flexibility and customization options for the Dapr workflow client.

Signed-off-by: Michiel van Praat <michiel.vanpraat@humandigital.nl>
Co-authored-by: Michiel van Praat <michiel.vanpraat@humandigital.nl>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Fix for DI registration not completing as expected (#1386)

* Tentative fix for DI registration not completing as expected

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Making injected IConfiguration optional as it might not be populated if user isn't utilizing ASP.NET Core from caller

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed DI injection issue

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed registration of DaprWorkflowClientBuilderFactory

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated field names for consistency

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Minor formatting changes

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed build error caused by bad merge resolution

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Add .NET client for pub/sub support - streaming subscriptions (#1381)

* Building out Dapr.Messaging and test project for streaming pubsub subscriptions

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added copyright notices

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Minor stylistic updates

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added generic client builder to support publish/subscribe client builder

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Tweaked XML comment

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added several unit tests for the generic client builder

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to include latest review changes:
- Added lock so that while we guarantee the method is called only once, it should be thread-safe now
- Marked PublishSubscribeReceiver as internal so its members aren't part of the public API
- Updated TopicMessage to use IReadOnlyDictionary

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Switched to interlock exchange instead of lock to slightly simplify code

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added sample project

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Minor changes to unit test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Deleted protos folder

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Using lowercase protos dir name

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added registration extension methods

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated example to use DI registration

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added default cancellation token

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Passing stream into method instead of creating it twice

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* ci: set fail-fast to false (#1405)

Signed-off-by: Mike Nguyen <hey@mike.ee>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Added async operations workflow sample (#1394)

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Added workflow example: Fan out/fan in (#1396)

* Added workflow fan out/fan in example

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added copyright headers

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Added workflow sample: Sub-workflows (#1395)

* Added Workflow with sub-workflow

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed duplicate package version reference

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Added workflow sample: Task chaining (#1387)

* Added Workflow Task Chaining example to replace https://github.com/dapr/dotnet-sdk/pull/1206

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Targeting .NET 6, fixed transposition error

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing copyright headers

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Added workflow sample: Monitor (#1388)

* Added workflow monitor

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Restore to original argument names

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Update to target .NET 6

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing copyright headers

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Added workflow example: External interaction (#1389)

* Added workflow example demonstrating external interaction

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added copyright headers

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed .sln file

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Optional DI lifecycle change (#1408)

* Added mechanism to allow the service lifetime to be overridden from a singleton (default) to another lifetime

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit tests - updated dependencies accordingly

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added service lifetime to DaprClient as well

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added update to DaprClient to pass service lifetime through

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added documentation indicating how to register DaprWorkflowClient with different lifecycle options.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unnecessary line from csproj

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Simplified registrations

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Called out an important point about registrations

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Additional lifecycle registration changes (#1410)

* Added service lifetime to Jobs client

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added service lifetime to messaging client

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added service lifetime to actors registration

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit tests for DaprClient

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Minor naming tweaks

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed invalid using

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added service lifetime tests for actors

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit tests for jobs client lifecycle registrations

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit tests for PubSub and lifecycle registration

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed missing registration dependency

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Preserve comparer of the original dictionary from ConfigurationProvider (#935)

Signed-off-by: Tomas Hrebicek <tomhreb@users.noreply.github.com>
Co-authored-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Update all.sln

Removed duplicate project include of Dapr.Workflow.Test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Bug/476 multiple methods per interface with JSON serialization doesn´t work (#1343)

* update devcontainer

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* update test setup

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* Now the json serialization should work with multiple methods in an interface

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* fixed devcontainer to run actors

Now the devcontainer uses docker in docker, so you can reach the dapr setup after you did run dapr init. This will then only affect the dev container, without compromising the host of the devcontainer

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* fix bugs with the current implementation

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* add a test that checks excatly the behavior

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* fix devcontainer post creatd command

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* change the default to dotnet 8.0

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* I don't know what is different but we commit.

Maybe it resolves the need of chmod for it 🤷‍♀️

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* make it easier to see why the application of an E2E test couldn't start

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* make the exception in E2E more percise

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* fix exception message

Signed-off-by: paule96 <paul-jeschke@outlook.com>

---------

Signed-off-by: paule96 <paul-jeschke@outlook.com>
Co-authored-by: Yaron Schneider <schneider.yaron@live.com>
Co-authored-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Support .NET 9 (#1404)

* Updated build and integration test scripts to include .NET 9

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unused matrix values

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Reverted some .NET 8 requirement

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated setup-dotnet to use latest action version + updated script to prefer a GA release, but use RC if available.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unnecessary secondary build step

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updating TFM moniker

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added test to install VStest

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Rolling back use of tool as it doesn't independently exist outside of the SDK

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added .NET 9 to build targets

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added .NET 9 to target frameworks across solution

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* I understand the reason for the required install step now - adding it back with a .NET 9 install step

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Placing install steps before build

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updating global.json

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Disabled analyzer errors in unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added .NET 9 to test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Changed from #pragma error to #pragma warning

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed unit tests to resolve analyzer warning

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated integration test to always include .NET 8 and .NET 9 installs

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Falling back to add separate .NET 9 support
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated referenced projects to target appropriate frameworks

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added all target frameworks back to Dapr.Commono

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added warnings to fix nullability analyzer warnings when targeting .NET 6

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated build step to use .NET 9 instead

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed cloud event middleware tests - the ApplicationBuilder requires a non-null ServiceProvider per https://learn.microsoft.com/en-us/dotnet/core/compatibility/extensions/8.0/activatorutilities-createinstance-null-provider

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Including target for .NET 6, 7, 8 and 9

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Trialing fix to E2E integration test - excluding use of AppWebApplicationFactory in favor of direct use of HttpClient

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Reverting as it breaks the other .NET versions

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Potentially fixed unit tests in .NET 9

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed extra line from build definition

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated documentation to reflect .NET 9 and a note highlighting that .NET 6 and .NET 7 will be deprecated in v1.16

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unintentionally added file to commit

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added .NET 9 to E2E test setup

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed typo

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed RC version from .NET 9 build

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Apparently the solution file got a minor change

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unnecessary null checks

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Whoops - didn't mean to commit that project to the solution

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* update .net workflow docs to stable (#1418)

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* FIX: Actor source generator generates invalid code for generic interfaces (#1419)

* Handled generic actor interface

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added more actor examples

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated actor namespace in example project

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

---------

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>
Co-authored-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Add .NET client for LLM Conversations support (#1382)

* Updated prototype

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added Dapr.AI project and unit test project to contain the conversational building block (and potentially future other projects)

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Changed default values

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unnecessary method

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added a few unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added example project

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing copyright headers

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Changed type name -> DaprLlmInput to DaprConversationInput

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Returning read only list

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Update to use IReadOnlyDictionary

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added method to abstract class

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Striving for consistency in how properties are specified on the record

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Refactored enum extensions out to Dapr.Common since it will be used in AI project

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added JSON converter for System.Text.Json to handle enum serialization based on the enum member attributes

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit tests to prove out generic enum JSON converter using EnumMember attributes

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added JSON converter to new enum for Dapr Conversation role

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Set up role to map to the string used in grpc call to sidecar

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* No need for the JSON converter after all

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing package version to fix build error

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed duplicate using statement breaking build

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed missing [Fact] annotation

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated proto types to reflect type name changes in https://github.com/dapr/dapr/pull/8250

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added support for service lifetime

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Building out documentation for Dapr AI

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Simplified registration

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Tweaked package version

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Using IConfiguration to source DaprClient values if provided in service provider

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed Models.* directories, flattened into Conversation namespace

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Swapped out to use IReadOnlyDictionary

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added suggested optimization

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed bad using statement

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updates to use uniform method for standing up new Dapr clients

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed duplicate project reference

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed build error

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixing build errors

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed bad references

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed several build errors

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixing more build errors

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to fix several build errors

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed bad refernce

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixing more build errors

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Role is required when submitting conversation input

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed impossible path since the role cannot be nullable

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed impossible path from logic now that role cannot be null

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Updated protos to latest in dapr/dapr (#1420)

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Conversation builder consistency changes (#1423)

* Corrected several unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated extension name for consistency

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated registration name for consistency

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* #906 -Added methods in status API supports for saving and reading binary data (#1116)

* Added methods in status API supports for direct storage and reading of byte arrays #906

Signed-off-by: Divya Perumal <divzi.perumal@gmail.com>
Signed-off-by: Divya Perumal <diperuma@microsoft.com>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Fixes + unit tests for streaming PubSub implementation (#1415)

* Added null check - the proto suggests this shouldn't ever be null, but there's an issue reporting as much, so this fixes that

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed the Task.WhenAll making the operation non-blocking

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit test to validate that the subscription is no longer blocking

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unused line from previous test, added another test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added another test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* More unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added more unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to make DaprPublishSubscribeClientBuilder configurable via a registered IConfiguration

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing copyright statements

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing package reference

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed bad reference (missed in merge)

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed failing unit test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Tweak to only pass along EventMessage payloads to developers as it's expected that the initial response will be null if EventMessage is populated

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Was missing assignment of the Data property in the TopicMessage. Shout out to both @tommorvolloriddle and @Aimless321 for catching this!

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fix - return would be bad. Continue is the right move.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added a simple test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Merged in tweaks from #1422

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Fix nulls

Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Delete examples/Client/PublishSubscribe/StreamingSubscriptionExample/Properties/launchSettings.json

Signed-off-by: Siri Varma Vegiraju <siri.varma@outlook.com>

* Delete examples/AI/ConversationalAI/Properties/launchSettings.json

Signed-off-by: Siri Varma Vegiraju <siri.varma@outlook.com>

* Delete daprdocs/content/en/dotnet-sdk-docs/dotnet-ai/dotnet-ai-usage.md

Signed-off-by: Siri Varma Vegiraju <siri.varma@outlook.com>

* Update dotnet-jobs-howto.md

Signed-off-by: Siri Varma Vegiraju <siri.varma@outlook.com>

* Update dotnet-jobs-howto.md

Signed-off-by: Siri Varma Vegiraju <siri.varma@outlook.com>

* Update dotnet-workflowclient-usage.md

Signed-off-by: Siri Varma Vegiraju <siri.varma@outlook.com>

* Update dotnet-workflowclient-usage.md

Signed-off-by: Siri Varma Vegiraju <siri.varma@outlook.com>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* fix thing

Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Update WorkflowActivityContext.cs

Signed-off-by: Siri Varma Vegiraju <siri.varma@outlook.com>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Update WorkflowActivityContext.cs

Signed-off-by: Siri Varma Vegiraju <siri.varma@outlook.com>

* Fix version

Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Update Dapr.Workflow.Test.csproj

Signed-off-by: Siri Varma Vegiraju <siri.varma@outlook.com>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* fix things

Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Delete examples/AI/ConversationalAI/Properties/launchSettings.json

Signed-off-by: Siri Varma Vegiraju <siri.varma@outlook.com>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Delete examples/Client/PublishSubscribe/StreamingSubscriptionExample/Properties/launchSettings.json

Signed-off-by: Siri Varma Vegiraju <siri.varma@outlook.com>
Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>

* Update WorkflowActivityContext.cs

Signed-off-by: Siri Varma Vegiraju <siri.varma@outlook.com>

---------

Signed-off-by: Siri Varma Vegiraju <svegiraju@microsoft.com>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>
Signed-off-by: Rafael Camara <rafaelcamarac@gmail.com>
Signed-off-by: Rafael Câmara <52082556+RafaelJCamara@users.noreply.github.com>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>
Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
Signed-off-by: Michiel van Praat <michiel.vanpraat@humandigital.nl>
Signed-off-by: Mike Nguyen <hey@mike.ee>
Signed-off-by: Tomas Hrebicek <tomhreb@users.noreply.github.com>
Signed-off-by: paule96 <paul-jeschke@outlook.com>
Signed-off-by: Divya Perumal <divzi.perumal@gmail.com>
Signed-off-by: Divya Perumal <diperuma@microsoft.com>
Signed-off-by: Siri Varma Vegiraju <siri.varma@outlook.com>
Co-authored-by: Siri Varma Vegiraju <svegiraju@microsoft.com>
Co-authored-by: Manuel Menegazzo <mmenegazzo@battistellacompany.it>
Co-authored-by: Whit Waldo <whit.waldo@innovian.net>
Co-authored-by: Shubhdeep Singh <shubhdeepsingh1502@gmail.com>
Co-authored-by: Ilias <polil91@hotmail.com>
Co-authored-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>
Co-authored-by: Rafael Câmara <52082556+RafaelJCamara@users.noreply.github.com>
Co-authored-by: Phillip Hoff <phillip@orst.edu>
Co-authored-by: Shivam Kumar <shivamkm07@gmail.com>
Co-authored-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com>
Co-authored-by: Ruud van Falier <119449492+humandigital-ruud@users.noreply.github.com>
Co-authored-by: Michiel van Praat <michiel.vanpraat@humandigital.nl>
Co-authored-by: Mike Nguyen <hey@mike.ee>
Co-authored-by: Tomas Hrebicek <tomhreb@users.noreply.github.com>
Co-authored-by: paule96 <paul-jeschke@outlook.com>
Co-authored-by: Yaron Schneider <schneider.yaron@live.com>
Co-authored-by: Divya Perumal <38757978+divzi-p@users.noreply.github.com>
2024-12-28 13:24:20 -06:00
jev-e da8b21bac4
Support gRPC richer error model (#1436)
* First pass at supporting richer error model in Dapr .NET SDK

Signed-off-by: jev-e <jev@jev.org.uk>
Signed-off-by: jev <jacob@jev.org.uk>

* Add ExtendedErrorDetailFactory, move to seperate files / new folder, add test file.

Signed-off-by: jev <jacob@jev.org.uk>

* Flesh out + rename tests file, tidy more comments.

Signed-off-by: jev <jacob@jev.org.uk>

* Add metadata to ErrorInfo details, add tests for each details type, multiple details

Signed-off-by: jev jacob@jev.org.uk
Signed-off-by: jev <jacob@jev.org.uk>

* Tidy up comments, add copyright to file.

Signed-off-by: jev jacob@jev.org.uk
Signed-off-by: jev <jacob@jev.org.uk>

* add and use constants, more docs tidy up.

Signed-off-by: jev jacob@jev.org.uk
Signed-off-by: jev <jacob@jev.org.uk>

* add initial docs pages for error handling in .net sdk.

Signed-off-by: jev jacob@jev.org.uk
Signed-off-by: jev <jacob@jev.org.uk>

* write daprdocs detailing usage of extendedErrorInfo, rename vars

signed-off-by: jev jacob@jev.org.uk
Signed-off-by: jev <jacob@jev.org.uk>

* Address PR comments

Signed-off-by: jev <jacob@jev.org.uk>

* pr comment; adjust weight

Signed-off-by: jev <jacob@jev.org.uk>

---------

Signed-off-by: jev-e <jev@jev.org.uk>
Signed-off-by: jev <jacob@jev.org.uk>
Signed-off-by: jev jacob@jev.org.uk
2024-12-28 12:56:47 -06:00
Whit Waldo a61db8bf97
Adds workflow replay-safe logger (#1434)
* Removed obsolete type

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing using

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Adding interface for IWorkflowContext for replayability concerns

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unused IConfiguration

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added ReplaySafeLogger type

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Building out functionality to expose ReplayLogger in workflow context

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added license information to file

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unnecessary file

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated copyright header for different project, made some tweaks for nullability errors

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added virtual methods that use the already-available ILoggerFactory to create the ReplaySafeLogger on the WorkflowContext

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unnecessary registration

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated example to demonstrate using ReplaySafeLogger in the orchestration context

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Tweaks on visibility and abstraction so that the methods are available in the context made visible to workflow developers

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed obsolete type registrations

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Simplified argument null check

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed since-removed code leftover from merge

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added documentation demonstrating how to access the replay-safe logger

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unnecessary and separate ReplaySafeLogger in favor of method to create it off the TaskOrchestrationContext (innerContext)

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-12-19 16:23:46 -06:00
Phillip Hoff 2849ec6341
Add RELEASE doc. (#1433)
Signed-off-by: Phillip Hoff <phillip@orst.edu>
2024-12-17 18:47:53 -06:00
Whit Waldo 1454043ff8
Updating Dapr .NET SDK documentation (#1409)
* Updated documentation to reflect new DaprClient DI injection capabilities

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Clarified relationship between DAPR_HTTP_ENDPOINT and DAPR_HTTP_PORT as well as DAPR_GRPC_ENDPOINT and DAPR_GRPC_PORT.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Clarified configuration prioritization order on DaprClientBuilder as of 1.15 and provided more information/example around sourcing from IConfiguration.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed typo - great catch Philip!

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added information about using Dapr.Jobs favoring dependency injection

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Building out .NET AI docs

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Building out .NET AI docs

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added first-draft of .NET Aspire docs

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added first-draft of .NET Aspire docs

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added first-draft of .NET Aspire docs

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Reordered the weighting of the development docs to reflect investment level

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated .NET SDK links to point to a better endpoint

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated more of the .NET SDK links

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Reweighted document order

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Building out pubsub docs

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Tweak to clarify use of the Dapr SDK

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing whitespace for clarity

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Simplified alert about .NET versioning

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added Dapr.Jobs as a prereq

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added some minor formatting tweaks

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added body of the pubsub how to documentation

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated table layout + reformatted

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added note about using DI functionality in best practices

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed several typos

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Corrected updated overload

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added best practices documentation for PubSub functionality

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated contribution guide

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added current .NET version support to contributor guide

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Minor word addition

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Renamed for consistency

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Tweaks to introduction text

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added Conversation usage documentation

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to reflect updated extension method name following merge of #1423

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Built out Jobs introduction

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated support message for Dapr.Workflows

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-12-12 11:07:27 -06:00
Whit Waldo 3d500e84f7
Fixes + unit tests for streaming PubSub implementation (#1415)
* Added null check - the proto suggests this shouldn't ever be null, but there's an issue reporting as much, so this fixes that

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed the Task.WhenAll making the operation non-blocking

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit test to validate that the subscription is no longer blocking

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unused line from previous test, added another test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added another test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* More unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added more unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to make DaprPublishSubscribeClientBuilder configurable via a registered IConfiguration

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing copyright statements

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing package reference

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed bad reference (missed in merge)

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed failing unit test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Tweak to only pass along EventMessage payloads to developers as it's expected that the initial response will be null if EventMessage is populated

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Was missing assignment of the Data property in the TopicMessage. Shout out to both @tommorvolloriddle and @Aimless321 for catching this!

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fix - return would be bad. Continue is the right move.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added a simple test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Merged in tweaks from #1422

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-12-11 15:29:39 -06:00
Divya Perumal 3a930c26d2
#906 -Added methods in status API supports for saving and reading binary data (#1116)
* Added methods in status API supports for direct storage and reading of byte arrays #906

Signed-off-by: Divya Perumal <divzi.perumal@gmail.com>
Signed-off-by: Divya Perumal <diperuma@microsoft.com>
2024-12-11 14:41:14 -06:00
Whit Waldo ccf2bfdce3
Conversation builder consistency changes (#1423)
* Corrected several unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated extension name for consistency

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated registration name for consistency

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-12-11 13:42:23 -06:00
Whit Waldo 8bc031887e
Updated protos to latest in dapr/dapr (#1420)
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-12-10 22:17:00 -06:00
Whit Waldo 7b5ca4fb6c
Add .NET client for LLM Conversations support (#1382)
* Updated prototype

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added Dapr.AI project and unit test project to contain the conversational building block (and potentially future other projects)

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Changed default values

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unnecessary method

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added a few unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added example project

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing copyright headers

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Changed type name -> DaprLlmInput to DaprConversationInput

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Returning read only list

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Update to use IReadOnlyDictionary

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added method to abstract class

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Striving for consistency in how properties are specified on the record

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Refactored enum extensions out to Dapr.Common since it will be used in AI project

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added JSON converter for System.Text.Json to handle enum serialization based on the enum member attributes

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit tests to prove out generic enum JSON converter using EnumMember attributes

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added JSON converter to new enum for Dapr Conversation role

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Set up role to map to the string used in grpc call to sidecar

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* No need for the JSON converter after all

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing package version to fix build error

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed duplicate using statement breaking build

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed missing [Fact] annotation

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated proto types to reflect type name changes in https://github.com/dapr/dapr/pull/8250

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added support for service lifetime

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Building out documentation for Dapr AI

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Simplified registration

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Tweaked package version

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Using IConfiguration to source DaprClient values if provided in service provider

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed Models.* directories, flattened into Conversation namespace

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Swapped out to use IReadOnlyDictionary

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added suggested optimization

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed bad using statement

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updates to use uniform method for standing up new Dapr clients

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed duplicate project reference

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed build error

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixing build errors

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed bad references

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed several build errors

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixing more build errors

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to fix several build errors

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed bad refernce

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixing more build errors

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Role is required when submitting conversation input

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed impossible path since the role cannot be nullable

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed impossible path from logic now that role cannot be null

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-12-10 09:06:44 -06:00
Manuel Menegazzo cfd4fbee84
FIX: Actor source generator generates invalid code for generic interfaces (#1419)
* Handled generic actor interface

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added more actor examples

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated actor namespace in example project

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

---------

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>
Co-authored-by: Whit Waldo <whit.waldo@innovian.net>
2024-12-05 11:36:45 -06:00
Hannah Hunter 232f461682
update .net workflow docs to stable (#1418)
Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
2024-12-04 13:12:02 -06:00
Whit Waldo da01dcd644
Support .NET 9 (#1404)
* Updated build and integration test scripts to include .NET 9

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unused matrix values

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Reverted some .NET 8 requirement

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated setup-dotnet to use latest action version + updated script to prefer a GA release, but use RC if available.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unnecessary secondary build step

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updating TFM moniker

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added test to install VStest

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Rolling back use of tool as it doesn't independently exist outside of the SDK

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added .NET 9 to build targets

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added .NET 9 to target frameworks across solution

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* I understand the reason for the required install step now - adding it back with a .NET 9 install step

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Placing install steps before build

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updating global.json

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Disabled analyzer errors in unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added .NET 9 to test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Changed from #pragma error to #pragma warning

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed unit tests to resolve analyzer warning

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated integration test to always include .NET 8 and .NET 9 installs

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Falling back to add separate .NET 9 support
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated referenced projects to target appropriate frameworks

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added all target frameworks back to Dapr.Commono

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added warnings to fix nullability analyzer warnings when targeting .NET 6

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated build step to use .NET 9 instead

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed cloud event middleware tests - the ApplicationBuilder requires a non-null ServiceProvider per https://learn.microsoft.com/en-us/dotnet/core/compatibility/extensions/8.0/activatorutilities-createinstance-null-provider

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Including target for .NET 6, 7, 8 and 9

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Trialing fix to E2E integration test - excluding use of AppWebApplicationFactory in favor of direct use of HttpClient

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Reverting as it breaks the other .NET versions

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Potentially fixed unit tests in .NET 9

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed extra line from build definition

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated documentation to reflect .NET 9 and a note highlighting that .NET 6 and .NET 7 will be deprecated in v1.16

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unintentionally added file to commit

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added .NET 9 to E2E test setup

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed typo

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed RC version from .NET 9 build

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Apparently the solution file got a minor change

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unnecessary null checks

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Whoops - didn't mean to commit that project to the solution

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-12-03 23:50:42 -06:00
paule96 2e0fa8026a
Bug/476 multiple methods per interface with JSON serialization doesn´t work (#1343)
* update devcontainer

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* update test setup

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* Now the json serialization should work with multiple methods in an interface

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* fixed devcontainer to run actors

Now the devcontainer uses docker in docker, so you can reach the dapr setup after you did run dapr init. This will then only affect the dev container, without compromising the host of the devcontainer

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* fix bugs with the current implementation

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* add a test that checks excatly the behavior

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* fix devcontainer post creatd command

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* change the default to dotnet 8.0

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* I don't know what is different but we commit.

Maybe it resolves the need of chmod for it 🤷‍♀️

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* make it easier to see why the application of an E2E test couldn't start

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* make the exception in E2E more percise

Signed-off-by: paule96 <paul-jeschke@outlook.com>

* fix exception message

Signed-off-by: paule96 <paul-jeschke@outlook.com>

---------

Signed-off-by: paule96 <paul-jeschke@outlook.com>
Co-authored-by: Yaron Schneider <schneider.yaron@live.com>
Co-authored-by: Whit Waldo <whit.waldo@innovian.net>
2024-12-03 14:26:00 -06:00
Tomas Hrebicek 80f0c749ea
Preserve comparer of the original dictionary from ConfigurationProvider (#935)
Signed-off-by: Tomas Hrebicek <tomhreb@users.noreply.github.com>
Co-authored-by: Whit Waldo <whit.waldo@innovian.net>
2024-11-29 23:16:18 -06:00
Whit Waldo 0b80c853b6
Additional lifecycle registration changes (#1410)
* Added service lifetime to Jobs client

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added service lifetime to messaging client

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added service lifetime to actors registration

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit tests for DaprClient

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Minor naming tweaks

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed invalid using

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added service lifetime tests for actors

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit tests for jobs client lifecycle registrations

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit tests for PubSub and lifecycle registration

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed missing registration dependency

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-11-24 02:14:10 -06:00
Whit Waldo ef04cad901
Optional DI lifecycle change (#1408)
* Added mechanism to allow the service lifetime to be overridden from a singleton (default) to another lifetime

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit tests - updated dependencies accordingly

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added service lifetime to DaprClient as well

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added update to DaprClient to pass service lifetime through

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added documentation indicating how to register DaprWorkflowClient with different lifecycle options.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unnecessary line from csproj

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Simplified registrations

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Called out an important point about registrations

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-11-21 15:40:20 -06:00
Whit Waldo f769eb1205
Added workflow example: External interaction (#1389)
* Added workflow example demonstrating external interaction

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added copyright headers

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed .sln file

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-11-18 12:48:53 -06:00
Whit Waldo 57a656bd2b
Added workflow sample: Monitor (#1388)
* Added workflow monitor

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Restore to original argument names

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Update to target .NET 6

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing copyright headers

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-11-14 11:48:38 -07:00
Whit Waldo 9d838fca9c
Added workflow sample: Task chaining (#1387)
* Added Workflow Task Chaining example to replace https://github.com/dapr/dotnet-sdk/pull/1206

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Targeting .NET 6, fixed transposition error

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing copyright headers

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-11-14 10:26:25 -07:00
Whit Waldo 651e5c74cb
Added workflow sample: Sub-workflows (#1395)
* Added Workflow with sub-workflow

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed duplicate package version reference

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-11-14 10:04:49 -07:00
Whit Waldo f3979ec080
Added workflow example: Fan out/fan in (#1396)
* Added workflow fan out/fan in example

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added copyright headers

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-11-13 12:34:02 -07:00
Whit Waldo 74a98111dc
Added async operations workflow sample (#1394)
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-11-12 14:08:21 -07:00
Mike Nguyen 6e2841a14a
ci: set fail-fast to false (#1405)
Signed-off-by: Mike Nguyen <hey@mike.ee>
2024-11-12 10:03:12 -07:00
Whit Waldo 91ee78aff4
Add .NET client for pub/sub support - streaming subscriptions (#1381)
* Building out Dapr.Messaging and test project for streaming pubsub subscriptions

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added copyright notices

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Minor stylistic updates

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added generic client builder to support publish/subscribe client builder

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Tweaked XML comment

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added several unit tests for the generic client builder

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to include latest review changes:
- Added lock so that while we guarantee the method is called only once, it should be thread-safe now
- Marked PublishSubscribeReceiver as internal so its members aren't part of the public API
- Updated TopicMessage to use IReadOnlyDictionary

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Switched to interlock exchange instead of lock to slightly simplify code

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added sample project

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Minor changes to unit test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Deleted protos folder

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Using lowercase protos dir name

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added registration extension methods

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated example to use DI registration

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added default cancellation token

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Passing stream into method instead of creating it twice

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-11-05 11:57:21 -06:00
Whit Waldo 682df6fec9
Fix for DI registration not completing as expected (#1386)
* Tentative fix for DI registration not completing as expected

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Making injected IConfiguration optional as it might not be populated if user isn't utilizing ASP.NET Core from caller

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed DI injection issue

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed registration of DaprWorkflowClientBuilderFactory

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated field names for consistency

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Minor formatting changes

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed build error caused by bad merge resolution

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-11-05 01:28:02 -06:00
Ruud van Falier e7d3c47615
Refactor DaprWorkflowClientBuilderFactory and WorkflowRuntimeOptions (#1244)
This commit refactors the DaprWorkflowClientBuilderFactory and WorkflowRuntimeOptions classes.

In DaprWorkflowClientBuilderFactory:
- Added a new method, UseGrpcChannelOptions, to allow the use of custom GrpcChannelOptions for creating the GrpcChannel.
- Updated the UseGrpc method to use the GrpcChannelOptions provided by the WorkflowRuntimeOptions.

In WorkflowRuntimeOptions:
- Added a new property, GrpcChannelOptions, to store the custom GrpcChannelOptions.
- Added a new method, UseGrpcChannelOptions, to set the GrpcChannelOptions.

These changes improve the flexibility and customization options for the Dapr workflow client.

Signed-off-by: Michiel van Praat <michiel.vanpraat@humandigital.nl>
Co-authored-by: Michiel van Praat <michiel.vanpraat@humandigital.nl>
2024-11-04 14:00:26 -06:00
Whit Waldo 7356c9dea2
Updated prereqs to specify .NET 6 and .NET 8 in v1.15 (#1398)
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-11-01 12:23:17 -05:00
Whit Waldo dfe7feef00
Add .NET client for Dapr Jobs API (#1384)
* Package addition + updates

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added Dapr.Jobs project

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Initial commit - unable to proceed without update on master from streaming sub PR

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added class to Dapr.Common, fixed compilation errors

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit tests for Dapr.Common enum extensions

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing copyright header

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added sample Jobs project

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added documentation

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing copyright header

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Downgraded Roslyn packages since master doesn't yet have the incremental source generator updates

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Missed a reference regarding incremental source generators

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Downgraded packages to fix nullability issues on build

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Downgraded from 8.* packages back to 6.* packages for the various Microsoft.Extensions.* packages to fix build issues

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unnecessary assignment

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added braces for clarity

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added more curley braces

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* More curly braces again

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Marked two properties as static

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to handle any order of parameters to endpoint route builder delegate

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated default cancellation token value

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing package version in Directory.Packages

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added test to ensure that even if cancellation token is provided, it'll handle the mapping properly

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-11-01 12:08:59 -05:00
Manuel Menegazzo 03038fa519
Incremental source generator for actors (#1334)
* Samples - Add k8s deployment yaml to DemoActor sample (#1308)

* up

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed build

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added scripts for image build

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added readme Build and push Docker image

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added demo-actor.yaml

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed typo

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated guide, fixed invocation throw curl

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Removed dockerfile, updated readme, removed ps1 and sh scripts

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated base image

Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Update demo-actor.yaml

Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added overload for DaprClient DI registration (#1289)

* Added overload for DaprClient DI registration allowing the consumer to easily use values from injected services (e.g. IConfiguration).

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added supporting unit test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Co-authored-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Merge `release-1.13` back into `master` (#1285)

* Update protos and related use for Dapr 1.13. (#1236)

* Update protos and related use.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Update Dapr runtime version.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Init properties.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

---------

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Update artifact action versions. (#1240)

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Make recursive true as default (#1243)

Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>

* Fix for secret key transformation in multi-value scenarios (#1274)

* Add repro test.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Fix for secret key transformation in multi-value scenarios.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

---------

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Update Dapr version numbers used during testing.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

---------

Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>
Co-authored-by: Shivam Kumar <shivamkm07@gmail.com>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

---------

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>
Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>
Co-authored-by: Whit Waldo <whit.waldo@innovian.net>
Co-authored-by: Phillip Hoff <phillip@orst.edu>
Co-authored-by: Shivam Kumar <shivamkm07@gmail.com>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Aligned nuget version

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* UP

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* UP

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Debug profile added

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated implementation

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Emitted DAPR001 Diagnostic warning

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added DAPR002 diagnostic

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Cleaun

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* UP

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added summaries

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added base interface to ActorClient

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added ctor

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added nullable directive

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added null check for actorproxy ctor parameter

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Moved DiagnoticException in a dedicate cs file

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Moved generator costants to dedicated class

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added ActorReference creation from the ActorBase class informations (#1277)

* Handled creation of ActorReference from Actor base class

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated null check

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added unit test for GetActorReference from null actore and actor proxy

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added test for ActorReference created inside Actor implementation

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated description

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed test method naming

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added unit test for exception generated in case the type is not convertible to an ActorReference

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

---------

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added overload to support SDK supplying query string on invoked URL (#1310)

* Refactored extensions and their tests into separate directories

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added overload to method invocation to allow query string parameters to be passed in via the SDK instead of being uncermoniously added to the end of the produced HttpRequestMessage URI

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit tests to support implementation

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Marking HttpExtensions as internal to prevent external usage and updating to work against Uri instead of HttpRequestMessage.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated unit tests to match new extension purpose

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Resolved an ambiguous method invocation wherein it was taking the query string and passing it as the payload for a request. Removed the offending method and reworked the remaining configurations so there's no API impact.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed actorProxy argument null check

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Moved ActorClientDesciptor into separta cs file

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Moved textual templates to dedicated class

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated comments, property names

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added argument null check to SyntaxFactoryHelpers

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added comments

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Removed obsolete testing packages https://github.com/dotnet/roslyn-sdk/blob/main/src/Microsoft.CodeAnalysis.Testing/README.md#obsolete-packages

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Adapted existing unit test to new source generated code

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Up

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added tests for SyntaxFactoryHelpers

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated generation of ArgumentNullException

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated nullability

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed internal methods tests

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added test to IEnumerableExtensions

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Unittested GetSyntaxKinds from Accessibility

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* UP

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated assignment implementation of ctor body

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Improved unit test

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added implementation of method generation

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed ArgumentNullException invocation

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added test for NameOfExpression

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed ActorProxy method invocation

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Simplified proxy argument definition

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Explicit generic arguments of the proxy call during generation

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Handled cancellation token with default value

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed typo

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Configured eol used in NormalizeWhitespace function

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Normalized expected source

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Moved to constat the ActorProxyTypeName

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fix typo

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Created ActorProxyInvokeMethodAsync SyntaxFactoryHelper

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Removed custom concat implementation

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* fix (#1329)

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* link to non-dapr endpoint howto (#1335)

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Merge 1.14 release branch back into `master`. (#1337)

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed merge errors
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated some summaries

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added some missing summaries

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed typo

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Improved some summary text

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Improved summaries

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Handled review requests

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Changed SyntaxFactoryHelpers accessor to internal

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

---------

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>
Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>
Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
Co-authored-by: Whit Waldo <whit.waldo@innovian.net>
Co-authored-by: Phillip Hoff <phillip@orst.edu>
Co-authored-by: Shivam Kumar <shivamkm07@gmail.com>
Co-authored-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com>
2024-10-28 09:20:31 -05:00
Rafael Câmara c61b15d5b1
Remove unused using statements. (#1313)
Signed-off-by: Rafael Camara <rafaelcamarac@gmail.com>
2024-10-24 17:00:09 -05:00
Rafael Câmara 94b97e224f
Remove unused variables (#1314)
* Remove unused variables

Signed-off-by: Rafael Camara <rafaelcamarac@gmail.com>
Signed-off-by: Rafael Câmara <52082556+RafaelJCamara@users.noreply.github.com>
Co-authored-by: Whit Waldo <whit.waldo@innovian.net>
2024-10-24 15:27:39 -05:00
Manuel Menegazzo ee8be67337
Removed sample folder (#1375)
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>
Co-authored-by: Whit Waldo <whit.waldo@innovian.net>
2024-10-22 04:33:13 -05:00
Manuel Menegazzo 5f21620ecf
cleanup: Removed Serilog nuget from Directory.Packages.props (#1376)
* Removed Serilog nuget from Directory.Packages.props

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Update Directory.Packages.props

Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>

---------

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>
Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>
2024-10-22 04:27:26 -05:00
Whit Waldo 5548c670f4
Prioritize retrieval of environment variables from IConfiguration instead of directly (#1363)
* Implemented against Dapr.Client.AspNetCore and Dapr.Client

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* SImplified DaprWorkflow DI registration and updated to use IConfiguration preference. Needs testing.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing copyright header

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated actor registration to prefer the updated IConfiguration-based approach for pulling the HTTP endpoint and API token

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Adopted accepted proposal's guidelines for favoring different environment variables for determining the sidecar endpoint. Added notes to explain this in the code going forward.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Made some lines a little more concise, added hostname default to DaprDefaults to use when building endpoints.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed and updated unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to put endpoint resolution mechanism in DaprDefaults within Dapr.Common  - updating projects and unit tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated packages to fix security advisory https://github.com/advisories/GHSA-447r-wph3-92pm

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated Workflow builder to use DaprDefaults with IConfiguration

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updating global.json

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Tweaked global.json comment

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Adding braces per nit

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Consolidated both registration extension methods to remove duplication

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-10-18 03:20:01 -05:00
Whit Waldo 1e148874bb
Updating actor serialization documentation (#1371)
* Changed headers, updated introduction to reflect the difference in serialization between either type and added a brief section to detail the use of System.Text.Json for weakly-typed Dapr actor clients and to point to official documentation on it

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-10-18 02:56:12 -05:00
Ilias d5c32f4ecb
Support case insensitive cloudevent payloads and forward cloudevent props s headers (#1153)
* forward cloudevent props
Signed-off-by: Ilias Politsopoulos <polil91@hotmail.com>

* refactor middleware
Signed-off-by: Ilias Politsopoulos <polil91@hotmail.com>

* add cloud event property filters
Signed-off-by: Ilias Politsopoulos <polil91@hotmail.com>

* update string check
Signed-off-by: Ilias Politsopoulos <polil91@hotmail.com>

* forward cloudevent props
Signed-off-by: Ilias Politsopoulos <polil91@hotmail.com>

* refactor middleware
Signed-off-by: Ilias Politsopoulos <polil91@hotmail.com>

* add cloud event property filters
Signed-off-by: Ilias Politsopoulos <polil91@hotmail.com>

* update checks
Signed-off-by: Ilias Politsopoulos <polil91@hotmail.com>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Co-authored-by: Whit Waldo <whit.waldo@innovian.net>
2024-10-17 17:39:39 -05:00
Shubhdeep Singh 23e8df0295
Improvement of the dotnet-contributing files (#1330)
Add link about Dapr bot to contribution documentation
2024-10-16 15:41:46 -05:00
Whit Waldo aa8b0fd351
Extracted Protos out to common project (#1367)
Protos pulled out to separate shared project
2024-10-16 00:36:20 -05:00
Whit Waldo 236567786e
Removes floating classes and introduces Dapr.Common project (#1365)
Extracting classes out to common project

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-10-16 00:21:52 -05:00
Whit Waldo 0a978458bb
Fixed security advisory updates across dependencies (transitive and direct) (#1366)
Migrating whole solution to Central Package Management - several package version upgrades to address security advisories and otherwise.

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-10-15 18:09:53 -05:00
Whit Waldo 2450ced25f
Adding instance-based CreateInvokableHttpClient (#1319)
This PR takes the implementation of the static method and puts it into the DaprClient instance, pulling from the existing apiTokenHeader on the instance to populate the daprApiToken, pulling the endpoint from the instance's httpEndpoint value and accepting only an appId argument so as to specify the ID of the Dapr app to connect to and place in the resulting URI.

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-10-14 18:18:36 -05:00
Whit Waldo 5b185ce729
Merge pull request #1362 from WhitWaldo/remove-workflow-methods-mergefix
Removed deprecated Workflow methods and types from DaprClient and tests
2024-10-14 15:34:35 -05:00
Whit Waldo 8948152a87 Merge branch 'remove-workflow-methods' into remote-workflow-methods-4
# Conflicts:
#	test/Dapr.E2E.Test/Workflows/WorkflowTest.cs
2024-10-14 13:11:21 -05:00
Whit Waldo 4d78706eb9
Merge pull request #1347 from WhitWaldo/additional-secrets-testing
Added unit test to Secrets API test suite
2024-10-11 02:28:44 -05:00
Whit Waldo 920d7ad80c Removed E2E workflow test as it validated DaprClient and the functionality has been moved out to the Dapr.Workflow project instead.
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-10-11 02:13:06 -05:00
Whit Waldo 72c53d841b
Merge branch 'master' into additional-secrets-testing 2024-10-11 02:06:31 -05:00
Whit Waldo 8948dd836f
Merge pull request #1355 from WhitWaldo/invoke-with-extra-headers
Test: Validate method invocation with extraneous headers
2024-10-11 02:02:44 -05:00
Whit Waldo ce4b674b28
Merge branch 'master' into invoke-with-extra-headers 2024-10-11 01:58:24 -05:00
Whit Waldo 19cb481557
Merge pull request #1353 from WhitWaldo/get-metadata-fix
Added fix to handle null return values from GetMetadataAsync
2024-10-11 01:57:52 -05:00
Whit Waldo c24a0828cd Removed unnecessary null check
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-10-11 01:47:37 -05:00
Whit Waldo 315b08ea50
Merge branch 'master' into additional-secrets-testing 2024-10-10 22:10:49 -05:00
Whit Waldo 1a7ca132a2
Merge branch 'master' into get-metadata-fix 2024-10-08 11:47:04 -05:00
Whit Waldo c47e65021b
Merge pull request #1315 from m3nax/consolidate-nuget-packages-version-used-in-test-projects
Consolidated version of nugets used in test project
2024-10-07 21:22:35 -05:00
Whit Waldo 512a021919
Merge branch 'master' into consolidate-nuget-packages-version-used-in-test-projects 2024-10-07 18:47:06 -05:00
Whit Waldo ba516bab32
Merge branch 'master' into invoke-with-extra-headers 2024-10-07 11:57:47 -05:00
Whit Waldo 156ed567ce Fixed spelling typo
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-10-07 10:47:24 -05:00
Whit Waldo 23f82fae5f Added unit test to validate that headers aren't being stripped off request
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-10-07 10:46:39 -05:00
Whit Waldo f11644e73c
Merge branch 'master' into get-metadata-fix 2024-10-06 02:41:58 -05:00
Whit Waldo bc62fd5b63 Added fix to handle null return values
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-10-06 02:29:53 -05:00
Whit Waldo a090d6635e Merge branch 'additional-secrets-testing' of https://github.com/WhitWaldo/dapr-dotnet-sdk into additional-secrets-testing 2024-09-19 08:28:08 -05:00
Whit Waldo 70d092ea79 Removed unused using
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-09-19 08:28:04 -05:00
Whit Waldo 2f20e1afbd
Merge branch 'master' into additional-secrets-testing 2024-09-19 08:25:50 -05:00
Whit Waldo 3d1fa01d0f
Added missing workflow status branch (#1348)
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-09-13 09:45:07 -07:00
Whit Waldo d355f044e5
Merge branch 'master' into additional-secrets-testing 2024-09-13 00:41:43 -05:00
Whit Waldo 167c5226a0 Added unit test to prove out concern raised on Discord
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-09-13 00:38:41 -05:00
Whit Waldo 366a3b390e Removed unused (and invalid) reference
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-09-03 18:45:36 -05:00
Whit Waldo 98be2a3717
Merge branch 'master' into remove-workflow-methods 2024-09-03 08:30:20 -05:00
Whit Waldo 0709a586f9 Removed deprecated methods from DaprClient and tests as well as unused types
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-09-03 06:30:41 -05:00
Phillip Hoff 74f6b0127f
Merge 1.14 release branch back into `master`. (#1337) 2024-08-21 23:47:39 -07:00
Hannah Hunter b8e2767289
link to non-dapr endpoint howto (#1335)
Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
2024-08-08 21:37:27 -07:00
Hannah Hunter 56367963f4
fix (#1329)
Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
2024-07-23 09:26:24 -07:00
Whit Waldo 3768a983b7
Added overload to support SDK supplying query string on invoked URL (#1310)
* Refactored extensions and their tests into separate directories

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added overload to method invocation to allow query string parameters to be passed in via the SDK instead of being uncermoniously added to the end of the produced HttpRequestMessage URI

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added unit tests to support implementation

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Marking HttpExtensions as internal to prevent external usage and updating to work against Uri instead of HttpRequestMessage.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated unit tests to match new extension purpose

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Resolved an ambiguous method invocation wherein it was taking the query string and passing it as the payload for a request. Removed the offending method and reworked the remaining configurations so there's no API impact.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-07-03 10:47:54 -07:00
Manuel Menegazzo ddce8a2972
Added ActorReference creation from the ActorBase class informations (#1277)
* Handled creation of ActorReference from Actor base class

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated null check

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added unit test for GetActorReference from null actore and actor proxy

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added test for ActorReference created inside Actor implementation

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated description

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed test method naming

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added unit test for exception generated in case the type is not convertible to an ActorReference

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

---------

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>
2024-06-26 14:37:19 -07:00
Manuel Menegazzo ad3cdbec37
Merge branch 'master' into consolidate-nuget-packages-version-used-in-test-projects 2024-06-26 19:10:46 +02:00
Manuel Menegazzo 76d2c3eada Consolidated version of coverlet.msbuild, coverlet.collector, xunit, xunit.runner.visualstudio, Microsoft.AspNetCore.Mvc.Testing, Moq to the same version in all projects.
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>
2024-06-26 19:10:32 +02:00
Manuel Menegazzo 84962532f1
Samples - Add k8s deployment yaml to DemoActor sample (#1308)
* up

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed build

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added scripts for image build

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added readme Build and push Docker image

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added demo-actor.yaml

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Fixed typo

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated guide, fixed invocation throw curl

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Removed dockerfile, updated readme, removed ps1 and sh scripts

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Updated base image

Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Update demo-actor.yaml

Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Added overload for DaprClient DI registration (#1289)

* Added overload for DaprClient DI registration allowing the consumer to easily use values from injected services (e.g. IConfiguration).

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added supporting unit test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Co-authored-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

* Merge `release-1.13` back into `master` (#1285)

* Update protos and related use for Dapr 1.13. (#1236)

* Update protos and related use.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Update Dapr runtime version.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Init properties.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

---------

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Update artifact action versions. (#1240)

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Make recursive true as default (#1243)

Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>

* Fix for secret key transformation in multi-value scenarios (#1274)

* Add repro test.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Fix for secret key transformation in multi-value scenarios.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

---------

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Update Dapr version numbers used during testing.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

---------

Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>
Co-authored-by: Shivam Kumar <shivamkm07@gmail.com>
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>

---------

Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>
Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>
Co-authored-by: Whit Waldo <whit.waldo@innovian.net>
Co-authored-by: Phillip Hoff <phillip@orst.edu>
Co-authored-by: Shivam Kumar <shivamkm07@gmail.com>
2024-06-26 09:19:53 -07:00
Phillip Hoff 512c9eaaf4
Merge `release-1.13` back into `master` (#1285)
* Update protos and related use for Dapr 1.13. (#1236)

* Update protos and related use.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Update Dapr runtime version.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Init properties.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

---------

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Update artifact action versions. (#1240)

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Make recursive true as default (#1243)

Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>

* Fix for secret key transformation in multi-value scenarios (#1274)

* Add repro test.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Fix for secret key transformation in multi-value scenarios.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

---------

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Update Dapr version numbers used during testing.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

---------

Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>
Co-authored-by: Shivam Kumar <shivamkm07@gmail.com>
2024-06-25 13:46:25 -07:00
Whit Waldo 2e94bb1905
Added overload for DaprClient DI registration (#1289)
* Added overload for DaprClient DI registration allowing the consumer to easily use values from injected services (e.g. IConfiguration).

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added supporting unit test

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Co-authored-by: Phillip Hoff <phillip@orst.edu>
2024-06-25 12:30:18 -07:00
Manuel Menegazzo fba9dfd531
Removed non-existent project, correct path of the generator project. (#1297)
Signed-off-by: Manuel Menegazzo <manuel.menegazzo@outlook.com>
2024-06-05 15:31:41 -07:00
Manuel Menegazzo 190156f212
Fixed badge broken links (#1290)
* Fixed badge broken links

Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>

* Update README.md

Co-authored-by: Marc Duiker <marcduiker@users.noreply.github.com>
Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>

---------

Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>
Co-authored-by: Marc Duiker <marcduiker@users.noreply.github.com>
2024-05-21 21:25:19 -07:00
Manuel Menegazzo 23c484e1f0
restored missing title in readme (#1286)
Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>
2024-05-14 10:08:06 -07:00
Manuel Menegazzo fd71812dc5
Update README.md (#1284)
Signed-off-by: Manuel Menegazzo <65919883+m3nax@users.noreply.github.com>
2024-05-13 09:41:46 -07:00
Carlos Mendible ba1341510b
Updated .github/holopin.yml. Fixes #1270 (#1276)
Signed-off-by: Carlos Mendible <266546+cmendible@users.noreply.github.com>
2024-04-23 08:53:51 -07:00
James Thompson ad3350f70e
#1239 remove polyfill packages (#1258)
Signed-off-by: James Thompson - SkiData <thompson.tomo@outlook.com>
Co-authored-by: Phillip Hoff <phillip@orst.edu>
2024-04-08 11:13:33 -07:00
Whit Waldo 64c2f4809b
Updated property on type to reflect the fact that it can return a null value (which it will if a key doesn't have any data in the state store). Only enabled nullable annotation on this file for now. (#1259)
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Co-authored-by: Phillip Hoff <phillip@orst.edu>
2024-04-08 10:56:19 -07:00
Whit Waldo ca0bffa440
Updating Workflow XML comment for accuracy (#1260)
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Co-authored-by: Phillip Hoff <phillip@orst.edu>
2024-04-08 10:33:55 -07:00
Elena Kolevska bdca3b320b
Adds an option to set a timeout for service invocation (#1252)
* Adds http timeout

Signed-off-by: Elena Kolevska <elena@kolevska.com>

* Adds a timeout for the grpc client

Signed-off-by: Elena Kolevska <elena@kolevska.com>

* Small updates

Signed-off-by: Elena Kolevska <elena@kolevska.com>

* Updates test

Signed-off-by: Elena Kolevska <elena@kolevska.com>

* Adds a timeout example in docs

Signed-off-by: Elena Kolevska <elena@kolevska.com>

* Adds e2e test for http service invocation

Signed-off-by: Elena Kolevska <elena@kolevska.com>

* Adds tests for grpc service invocation

Signed-off-by: Elena Kolevska <elena@kolevska.com>

* Removes grpc timeout, because it’s not needed. It can be passed directly to the call as shown in the updated tests and docs

Signed-off-by: Elena Kolevska <elena@kolevska.com>

* Update src/Dapr.Client/DaprClientBuilder.cs

Signed-off-by: Elena Kolevska <elena-kolevska@users.noreply.github.com>

---------

Signed-off-by: Elena Kolevska <elena@kolevska.com>
Signed-off-by: Elena Kolevska <elena-kolevska@users.noreply.github.com>
Co-authored-by: Phillip Hoff <phillip@orst.edu>
2024-04-08 10:23:49 -07:00
Whit Waldo 31af35b6c6
Updated to reflect latest guidance to register endpoints via top-level route registrations (#1262)
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-04-08 09:52:09 -07:00
Phillip Hoff 1b7c9f4f80
Merge 1.13 release branch back to master (#1247)
* Update protos and related use for Dapr 1.13. (#1236)

* Update protos and related use.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Update Dapr runtime version.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Init properties.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

---------

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Update artifact action versions. (#1240)

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Make recursive true as default (#1243)

Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>

* Make final 1.13 changes.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

---------

Signed-off-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>
Co-authored-by: Shivam Kumar <shivamkm07@gmail.com>
2024-03-08 09:48:58 -08:00
Phillip Hoff c07eb698ac
Source generated actor clients (#1165)
Signed-off-by: Phillip Hoff <phillip@orst.edu>
2024-02-16 11:35:29 -08:00
Phillip Hoff e244e88ac1
Use TryAddSingleton() for registering services. (#1238)
Signed-off-by: Phillip Hoff <phillip@orst.edu>
2024-02-16 11:29:42 -08:00
Whit Waldo 83858d779b
Add overload to deserialize GetBulkStateAsync item values (#1173)
* Adds overload to BulkStateItem and GetBulkStateAsync to perform SDK-based deserialization of returned values instead of strictly returning serialized strings.
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated method summary to better direct user towards one method or the other (typed or not)
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added comments to the typed BulkStateItem to better reflect the deserialized nature of the value.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Refactored GetBulkStateAsync method to a shared private method so both the non-generic and generic public methods can deserialize the data once as necessary.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed excessive space in comment.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Formatting: If we're separating parameters to separate lines, convention requires each have their own line.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
Co-authored-by: Phillip Hoff <phillip@orst.edu>
2024-02-16 11:23:58 -08:00
James Croft 034de3e233
Enable vault name mapping and error suppression (#1231)
* Added documentation detailing how serialization works using the DataContract serialization framework. (#1222)

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: James Croft <jamz_c@hotmail.co.uk>

* Weakly typed actor polymorphic and null responses (#1214)

Signed-off-by: Remco Blok <remco.blok@resilientenergy.com>
Co-authored-by: Remco Blok <remco.blok@resilientenergy.com>
Co-authored-by: Phillip Hoff <phillip@orst.edu>
Signed-off-by: James Croft <jamz_c@hotmail.co.uk>

* Enable vault name mapping and error suppression

Signed-off-by: Yash Nisar <yashnisar@microsoft.com>
Signed-off-by: James Croft <jamz_c@hotmail.co.uk>

* Add additional secret descriptor constructor for required without key map

Signed-off-by: James Croft <jamz_c@hotmail.co.uk>

* Update configuration load exception rethrow to match rules

Signed-off-by: James Croft <jamz_c@hotmail.co.uk>

* Add tests for required/not required exception handling

Signed-off-by: James Croft <jamz_c@hotmail.co.uk>

* Implementing Cryptography building block in .NET (#1217)

* Added method to DaprClient and GRPC implementation to call cryptography proto endpoints

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* First pass at implementing all exposed Cryptography methods on Go interface

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added examples for Cryptography block

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing copyright statements

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to properly support Crypto API this time

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added copyright statements

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed deprecated examples as the subtle APIs are presently disabled

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated example to reflect new API shape

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated example and readme

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added overloads for encrypting/decrypting streams instead of just fixed byte arrays. Added example demonstrating the same encrypting a file via a FileStream and decrypting from a MemoryStream.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added some unit tests to pair with the implementation

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added null check for the stream argument

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Changed case of the arguments as they should read "plaintext" and not "plainText"

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Reduced number of encryption implementations by just wrapping byte array into memory stream

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Constrainted returned member types per review suggestion

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated methods to use ReadOnlyMemory<byte> instead of byte[] - updated implementations to use low-allocation spans where possible (though ToArray is necessary to wrap with MemoryStream).

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to use encryption/decryption options instead of lots of method overload variations. Simplified gRPC implementation to use fewer methods. Applied argument name updates applied previously (plainText -> plaintext).

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unused reference

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated examples to reflect new method shapes. Downgraded package to .net 6 instead of .net 8 per review suggestion.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to reflect non-aliased values per review suggestion

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Update to ensure that both send/receive streams run at the same time instead of sequentially.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to support streamed results in addition to fixed byte arrays. Refactored implementation to minimize duplicative code.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated example to fix compile issue

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed encrypt/decrypt methods that accepted streams and returned ReadOnlyMemory<byte>. Marked implementations that use this on the gRPC class as private instead.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing Obsolete attributes on Encrypt/Decrypt methods. Added overloads on decrypt methods that do not require a DecryptionOptions to be passed in.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated encrypt/decrypt options so the streaming block size no longer uses a uint. Added validation in its place to ensure the value provided is never less than or equal to 0.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated how validation works in the options to accommodate lack of the shorter variation in .NET 6

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated names of encrypt/decrypt streaming methods so everything uses just EncryptAsync or DecryptAsync

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed regression that would have prevented data from being sent entirely to the sidecar. Also simplified operation per suggestion in review.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated examples to reflect changed API

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated so IAsyncEnumerable methods (encrypt and decrypt) return IAsyncEnumerable<ReadOnlyMemory<byte>> instead of IAsyncEnumerable<byte[]>.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated example to reflect change from IAsyncEnumerable<byte> to IAsyncEnumerable<ReadOnlyMemory<byte>>

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Avoiding allocation by using MemoryMarshal instead of .ToArray() to create MemoryStream from ReadOnlyMemory<byte>.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Performance updates to minimize unnecessary byte array copies and eliminate unnecessary allocations.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unnecessary return from SendPlaintextStreamAsync and SendCiphertextStreamAsync methods

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated exception text to be more specific as to what's wrong with the input value.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Minor tweak to prefer using using a Memory

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Deduplicated some of the Decrypt methods, simplifying the implementation

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Eliminated duplicate encryption method, simplifying implementation

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to eliminate an unnecessary `await` and `async foreach`.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated stream example to reflect the changes to the API shape

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added notes about operations with stream-based data

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: James Croft <jamz_c@hotmail.co.uk>

* Update DaprSecretDescriptor constructors and documentation

Signed-off-by: James Croft
Signed-off-by: James Croft <jamz_c@hotmail.co.uk>

* Remove DaprSecretStoreConfigurationProvider Console.WriteLine

Signed-off-by: James Croft <jamz_c@hotmail.co.uk>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
Signed-off-by: James Croft <jamz_c@hotmail.co.uk>
Signed-off-by: Remco Blok <remco.blok@resilientenergy.com>
Signed-off-by: Yash Nisar <yashnisar@microsoft.com>
Signed-off-by: James Croft
Co-authored-by: Whit Waldo <whit.waldo@innovian.net>
Co-authored-by: Remco Blok <remcoblok@hotmail.com>
Co-authored-by: Remco Blok <remco.blok@resilientenergy.com>
Co-authored-by: Phillip Hoff <phillip@orst.edu>
Co-authored-by: Yash Nisar <yashnisar@microsoft.com>
2024-02-16 09:10:46 -08:00
Nicolas Chaussé 817b60d9c6
Handle the case where appid contains at least one upperletter (#1233)
* Handle the case where appid can contain some uppercases

Signed-off-by: Nicolas Chaussé <chausse.nicolas@gmail.com>
Signed-off-by: TWEESTY <chausse.nicolas@gmail.com>
Signed-off-by: Nicolas Chaussé <chausse.nicolas@gmail.com>

* Add one test sample

Signed-off-by: Nicolas Chaussé <chausse.nicolas@gmail.com>
Signed-off-by: TWEESTY <chausse.nicolas@gmail.com>
Signed-off-by: Nicolas Chaussé <chausse.nicolas@gmail.com>

* Optimization in order to not add some overhead time for the "normal" use case

Signed-off-by: TWEESTY <chausse.nicolas@gmail.com>
Signed-off-by: Nicolas Chaussé <chausse.nicolas@gmail.com>

* Change comment which was false

Signed-off-by: TWEESTY <chausse.nicolas@gmail.com>
Signed-off-by: Nicolas Chaussé <chausse.nicolas@gmail.com>

* Remove the breaking change

Signed-off-by: TWEESTY <chausse.nicolas@gmail.com>
Signed-off-by: Nicolas Chaussé <chausse.nicolas@gmail.com>

* Simplify according to the review

Signed-off-by: Nicolas Chaussé <chausse.nicolas@gmail.com>

---------

Signed-off-by: Nicolas Chaussé <chausse.nicolas@gmail.com>
Signed-off-by: TWEESTY <chausse.nicolas@gmail.com>
2024-02-16 09:02:22 -08:00
Whit Waldo ca2fab2567
Implementing Cryptography building block in .NET (#1217)
* Added method to DaprClient and GRPC implementation to call cryptography proto endpoints

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* First pass at implementing all exposed Cryptography methods on Go interface

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added examples for Cryptography block

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing copyright statements

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to properly support Crypto API this time

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added copyright statements

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed deprecated examples as the subtle APIs are presently disabled

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated example to reflect new API shape

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated example and readme

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added overloads for encrypting/decrypting streams instead of just fixed byte arrays. Added example demonstrating the same encrypting a file via a FileStream and decrypting from a MemoryStream.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added some unit tests to pair with the implementation

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added null check for the stream argument

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Changed case of the arguments as they should read "plaintext" and not "plainText"

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Reduced number of encryption implementations by just wrapping byte array into memory stream

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Constrainted returned member types per review suggestion

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated methods to use ReadOnlyMemory<byte> instead of byte[] - updated implementations to use low-allocation spans where possible (though ToArray is necessary to wrap with MemoryStream).

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to use encryption/decryption options instead of lots of method overload variations. Simplified gRPC implementation to use fewer methods. Applied argument name updates applied previously (plainText -> plaintext).

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated tests

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unused reference

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated examples to reflect new method shapes. Downgraded package to .net 6 instead of .net 8 per review suggestion.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to reflect non-aliased values per review suggestion

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Update to ensure that both send/receive streams run at the same time instead of sequentially.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to support streamed results in addition to fixed byte arrays. Refactored implementation to minimize duplicative code.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated example to fix compile issue

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed encrypt/decrypt methods that accepted streams and returned ReadOnlyMemory<byte>. Marked implementations that use this on the gRPC class as private instead.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added missing Obsolete attributes on Encrypt/Decrypt methods. Added overloads on decrypt methods that do not require a DecryptionOptions to be passed in.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated encrypt/decrypt options so the streaming block size no longer uses a uint. Added validation in its place to ensure the value provided is never less than or equal to 0.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated how validation works in the options to accommodate lack of the shorter variation in .NET 6

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated names of encrypt/decrypt streaming methods so everything uses just EncryptAsync or DecryptAsync

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed regression that would have prevented data from being sent entirely to the sidecar. Also simplified operation per suggestion in review.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated examples to reflect changed API

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated so IAsyncEnumerable methods (encrypt and decrypt) return IAsyncEnumerable<ReadOnlyMemory<byte>> instead of IAsyncEnumerable<byte[]>.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated example to reflect change from IAsyncEnumerable<byte> to IAsyncEnumerable<ReadOnlyMemory<byte>>

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Avoiding allocation by using MemoryMarshal instead of .ToArray() to create MemoryStream from ReadOnlyMemory<byte>.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Performance updates to minimize unnecessary byte array copies and eliminate unnecessary allocations.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed unnecessary return from SendPlaintextStreamAsync and SendCiphertextStreamAsync methods

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated exception text to be more specific as to what's wrong with the input value.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Minor tweak to prefer using using a Memory

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Deduplicated some of the Decrypt methods, simplifying the implementation

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Eliminated duplicate encryption method, simplifying implementation

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated to eliminate an unnecessary `await` and `async foreach`.

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated stream example to reflect the changes to the API shape

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Added notes about operations with stream-based data

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-02-14 11:29:08 -08:00
Remco Blok 348d1430ba
Weakly typed actor polymorphic and null responses (#1214)
Signed-off-by: Remco Blok <remco.blok@resilientenergy.com>
Co-authored-by: Remco Blok <remco.blok@resilientenergy.com>
Co-authored-by: Phillip Hoff <phillip@orst.edu>
2024-01-30 21:33:15 -08:00
Whit Waldo d023a43ba4
Added documentation detailing how serialization works using the DataContract serialization framework. (#1222)
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
2024-01-26 10:34:12 -08:00
Josh van Leeuwen 233c620b0f
Actor State TTL (#1164)
* Actor state TTL support

Signed-off-by: joshvanl <me@joshvanl.dev>
2024-01-08 15:06:20 -08:00
MregXN 7616bfad22
use daprWorkflowClient (#1212)
Signed-off-by: MregXN <mregxn@gmail.com>
2024-01-08 14:14:07 -08:00
Farshad Davoudi 72284066f7
Update _index.md by fixing broken link (#1221)
Signed-off-by: Farshad Davoudi <f.davoudi.r@outlook.com>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2024-01-05 17:09:27 -08:00
Henrik Karström 0511b733a3
Fix example dotnet-actors-howto.md (#1218)
Fix example output to not repeat "Success"

Signed-off-by: Henrik Karström <henrik.karstrom@gmail.com>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2024-01-05 16:59:48 -08:00
Phillip Hoff 8d06a1f984
Enable `CancellationToken` for non-remoting actor implementations (#1202)
* Sketch no arguments with cancellation.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Sketch the other argument permutations.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Refactor tests.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Push HTTP request cancellation token down into handlers.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

---------

Signed-off-by: Phillip Hoff <phillip@orst.edu>
2024-01-05 16:43:51 -08:00
Ryan Lettieri 10ef81873b
Adding cancel to workflow example and updating api references to beta (#1194)
Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>
2023-11-29 14:39:56 -08:00
Frank Buckley e8204dca45
Correct spelling of "identified" (#1159)
Signed-off-by: Frank Buckley <frank@frankbuckley.com>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2023-11-29 11:09:13 -08:00
Marc Duiker 1cb00523a9
Add holopin.yml config (#1147)
Signed-off-by: Marc Duiker <marcduiker@users.noreply.github.com>
2023-11-28 16:38:09 -08:00
Josh van Leeuwen b669585b22
Updates Dapr to 1.12 in GitHub actions itest (#1185)
* Updates Dapr to 1.12 in GitHub actions

Signed-off-by: joshvanl <me@joshvanl.dev>

* Remove commit ref from github actions

Signed-off-by: joshvanl <me@joshvanl.dev>

* Fix case sensitive error string match case

Signed-off-by: joshvanl <me@joshvanl.dev>

---------

Signed-off-by: joshvanl <me@joshvanl.dev>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2023-11-28 16:28:52 -08:00
MregXN abcbf4f9a0
modify readme (#1192)
Signed-off-by: MregXN <mregxn@gmail.com>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2023-11-28 16:05:39 -08:00
Whit Waldo e435efda96
Added unit test to prove out enum serialization working as expected during event publish (#1174)
Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2023-11-28 15:55:34 -08:00
MregXN bb3f97abfd
Modify broken links in README (#1190)
Signed-off-by: MregXN <mregxn@gmail.com>
2023-11-28 15:48:15 -08:00
Phillip Hoff 09008bb43b
.NET 8 Support (#1188)
* Update test projects to use .NET 8.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Update SDK projects to target .NET 8.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

* Update workflows to target .NET 8.

Signed-off-by: Phillip Hoff <phillip@orst.edu>

---------

Signed-off-by: Phillip Hoff <phillip@orst.edu>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2023-11-15 10:48:02 -08:00
Ryan Lettieri 39a38f6e9b
Initial implementation for workflow log tracing (#1176)
* Initial setup for workflow log tracing

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Created log sink for E2E tests using serilog

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Formatting

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Addressing feedback on review

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Addressing some review comments

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Addressing more feedbck in the workflow e2e test

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

---------

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>
2023-11-14 12:17:17 -08:00
Phillip Hoff 2332388155
Update actor reminder example. (#1179)
Signed-off-by: Phillip Hoff <phillip@orst.edu>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2023-11-13 15:25:56 -08:00
Phillip Hoff 02ab25e937
Consolidate C# language version to 10. (#1180)
Signed-off-by: Phillip Hoff <phillip@orst.edu>
2023-11-13 15:20:01 -08:00
Ryan Lettieri 3b979e6bdb
Adding in new test for parallel raise events in workflow (#1155)
* Adding in new test for parallel raise events in workflow

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>
2023-10-06 11:37:38 -07:00
Fabian Martinez 99d874a2b1
set dapr-api-token to healthz requests when needed (#1145)
Signed-off-by: Fabian Martinez <46371672+famarting@users.noreply.github.com>
Co-authored-by: Yaron Schneider <schneider.yaron@live.com>
2023-09-07 15:21:11 -07:00
Ryan Lettieri 87329f62b1
Updating workflow collection to allow for use of API Token validation (#1141)
Updating workflow collection to allow for use of API Token validation

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>
2023-09-07 14:51:32 -07:00
Erik O'Leary fd7168fdfc
Proof-of-concept serialization of advanced JSON types, records (#1073)
* Add system text json support for actor serialization

Signed-off-by: Erik O'Leary <erik.m.oleary@gmail.com>

* Remove unnecessary stream; directly use serializetobytes

Signed-off-by: Erik O'Leary <erik.m.oleary@gmail.com>

* Disable parallel test execution to make test results more repeatable/predictable

Signed-off-by: Erik O'Leary <erik.m.oleary@gmail.com>

---------

Signed-off-by: Erik O'Leary <erik.m.oleary@gmail.com>
2023-09-05 12:16:45 -07:00
Yash Nisar 17f849b175
Remove .NET Core 3.1 support and standardize on .NET 6 (#1045)
* Remove .NET Core 3.1 support and standardize on .NET 6

Signed-off-by: Yash Nisar <yashnisar@microsoft.com>

* Remove support for .NET 5 as well

Signed-off-by: Yash Nisar <yashnisar@microsoft.com>

---------

Signed-off-by: Yash Nisar <yashnisar@microsoft.com>
2023-08-24 11:04:02 -07:00
vlardn 667dcaf441
Inroduce OnActorMethodFailedAsync virtual method for overriding (#1014)
Signed-off-by: Vlad Rudenko <vladislav.rudenko@gmail.com>
2023-08-16 09:49:12 -07:00
Shivam Kumar f4e02df980
adding get actor reminder API in docs (#1113)
Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>
2023-07-21 14:15:42 -07:00
Hannah Hunter 2449bcd669
remove invalid code line (#1127)
Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
2023-07-18 12:51:12 -07:00
Aaron Crawfis 6dae4e339d
Add cascading metadata (#1128)
Signed-off-by: Aaron Crawfis <Aaron.Crawfis@microsoft.com>
2023-07-18 11:39:16 -07:00
Artur Souza f788efabde
Add support to DAPR_HTTP_ENDPOINT and DAPR_GRPC_ENDPOINT env. (#1124)
Signed-off-by: Artur Souza <asouza.pro@gmail.com>
2023-07-18 11:25:17 -07:00
MonkeyTennis 574dc0cb3d
Rev'ed Grpc.Net.Client PackageReference version for Dapr dotnet-sdk (#1126)
Rev'ed Grpc.Net.Client PackageReference version for Dapr dotnet-sdk

Signed-off-by: Bradley Cotier <bcotier@microsoft.com>
2023-07-18 11:10:11 -07:00
Chris Gillum c99475be3c
[Workflow] Fix issue with ignored external event payload (#1119)
* [Workflow] Fix issue with ignored external event payload

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

* Pushing missing commits

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

* Remove unnecessary steps from itests.yml

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

---------

Signed-off-by: Chris Gillum <cgillum@microsoft.com>
2023-07-06 16:44:40 -07:00
Shubham Sharma 8e9db70c0f
Fix HTTP examples in Workflow Console App (#1107)
* Update demo.http;

Signed-off-by: Shubham Sharma <shubhash@microsoft.com>

* Fix input

Signed-off-by: Shubham Sharma <shubhash@microsoft.com>

---------

Signed-off-by: Shubham Sharma <shubhash@microsoft.com>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2023-06-15 17:07:36 -07:00
Bernd Verst be959f943c
Link to DotNet Fossa status (#1105)
Link to DotNet Fossa status

Signed-off-by: Bernd Verst <bverst@gmail.com>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2023-06-15 16:16:32 -07:00
halspang d673c446c5
Merge pull request #1112 from shivamkm07/merge_master
Merge release-1.11 to master
2023-06-15 16:06:08 -07:00
Shivam Kumar ece9fbe0d4 adding get actor reminder API (#1103)
* get actor reminder API

Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>

* handling serialization better

Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>

---------

Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>
2023-06-13 16:17:59 +05:30
Shivam Kumar edb09a08b7
removing alpha for config api in docs (#1100)
Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>
2023-05-25 12:53:45 -07:00
Hannah Hunter a4f5fc022d
add demo to how to (#1099)
Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2023-05-24 14:55:30 -07:00
Shivam Kumar e7a71c423a
removing Obsolete attribute from config API classes (#1098)
Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2023-05-24 14:05:33 -07:00
Chris Gillum a3e5106040
[Workflow] Add human approval to the workflow example (#1096)
* [Workflow] Add human approval to the workflow example

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

* Add RequestApprovalActivity to workflow

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

* PR feedback - explicit enum values

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

---------

Signed-off-by: Chris Gillum <cgillum@microsoft.com>
2023-05-24 10:43:54 -07:00
Hannah Hunter 364ed92f95
[dotnet-client] Add dist lock examples (#1095)
* add dist lock to dotnet client doc

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>

* attempt at naming scheme 1

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>

* yikes put it back

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>

* attempt 2

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>

* attempt 3

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>

---------

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
2023-05-22 10:54:35 -07:00
Chris Gillum e59c856b33
Proper workflow retry support in Dapr SDK (#1090)
Signed-off-by: Chris Gillum <cgillum@microsoft.com>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2023-05-19 09:22:13 -05:00
Hannah Hunter a2d3c3a48c
[docs] Update API calls in workflow example (#1083)
* update calls in the example

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>

* remove gitmodules

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>

* remove daprdocs/themes/docsy

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>

* fix links and add links

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>

* Fix workflow inputs and outputs for v1.11

---------

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
Co-authored-by: Chris Gillum <cgillum@gmail.com>
2023-05-18 09:25:21 -05:00
Chris Gillum 8152c7496a
[Workflow] Improve management API usability (#1087)
* [Workflow] Improve management API usability

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

* PR feedback and update E2E test

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

* PR feedback

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

---------

Signed-off-by: Chris Gillum <cgillum@microsoft.com>
2023-05-12 15:44:33 -07:00
Chris Gillum 610632ae4b
Add WorkflowTaskFailedException for workflow error handling (#1086)
Signed-off-by: Chris Gillum <cgillum@microsoft.com>
2023-05-11 13:11:49 -07:00
Ryan Lettieri 5a57035f44
Workflow addition of Pause/Resume and Purge (#1080)
* Initial Push for new workflow methods

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Updating proto and cleaning up workflow functions

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Updating runtime ver

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Updating go ver

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Updating go ver

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Temp removal of new workflow stuff to see if the test passes without it

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Another fix attempt for workflow test

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Attempting to change input for workflow E2E test

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Commenting out pause/resume for testing

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Correcting assert statement on workflow purge

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Fixing exception check

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Fixing exception check on purge

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* added in testing for raise event in workflow

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Pointing to wip for pause/resume fixes

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* First round of addresing feedback for workflow

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Addressing feedback

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* addressing more feedback

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* fixing startup.cs for workflow test

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* fixing startup.cs for workflow test again

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* changing variable type for workflow start

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Making code look nicer

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Updating workflow get for testing

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Checking against null updated time for workflow updated time

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Adding in a delay before getting info on the workflow

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Adding in a larger delay before getting info on the workflow

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Attempting to test against latest dapr dapr commit

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Removing other sleeps from workflow test

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Addressing more feedback

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Fixing assert statement on workflow purge test

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

---------

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>
2023-05-09 12:40:15 -07:00
Shivam Kumar 3d4ae5bfb1
Move config api to stable (#1077)
* updating protos

Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>

* updating config api to stable

Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>

* workflow changes to fix build failure

Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>

* updating go  version

Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>

* go version from dapr/cli repo

Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>

---------

Signed-off-by: Shivam Kumar <shivamkm07@gmail.com>
2023-05-03 12:00:54 -07:00
Tom Kerkhove 9b470cc6ae
fix: Use ignored variable in WorkflowServiceCollectionExtensions.AddDaprWorkflow (#1056)
Signed-off-by: Tom Kerkhove <kerkhove.tom@gmail.com>
2023-04-17 10:40:15 -07:00
Chris Gillum b97af45c5f
Workflow SDK changes for v1.11 (#1059)
* Workflow SDK changes for v1.11

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

* PR feedback - round 1

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

* PR feedback - update doc comment

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

---------

Signed-off-by: Chris Gillum <cgillum@microsoft.com>
2023-03-29 15:56:04 -07:00
Yash Nisar f42b690f4c
Merging changes from 1.10 to master (#1047)
* Update DurableTask SDK dependency to get ARM64 compatibility (#1024) (#1025)

* Update DurableTask SDK dependency to get ARM64 compatibility

* Fix issue with gRPC address override behavior

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

* Initial Bulk Subscribe functionality (#1009)

Signed-off-by: Yash Nisar <yashnisar@microsoft.com>

* Workflow unit testing changes for 1.10 release (#1038)

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

* Fix issue with gRPC address override behavior

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

* Workflow SDK changes to enable unit testing

Signed-off-by: Chris Gillum <cgillum@microsoft.com>
2023-02-27 14:42:32 -08:00
Hannah Hunter 45e6e43388
[docs] Add section for workflow (#1031)
* add section for workflow in .NET SDK docs

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>

* add initial draft

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>

* edit from Mark

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>

* quick pass and update from hal and chris

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
2023-02-27 10:59:12 -08:00
Tiago Alves Macambira 5ece9d02e0
Fix name in dicussion.md (#1026)
dicussion.md `name` field was colliding with feature_request.md `name`, causing both to be unusable.

Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>
2023-02-21 17:09:18 -08:00
Chris Gillum aa38b05af7
Enable unit testing for Dapr Workflows (#1035)
* Workflow SDK changes to enable unit testing

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

* Sample workflow unit testing project

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

---------

Signed-off-by: Chris Gillum <cgillum@microsoft.com>
2023-02-16 11:55:21 -08:00
Ryan Lettieri 9dcae7b0e7
Improved workflows example program and added in statestore functionality. (#1020)
* Workflow Management - Initial Methods (#1003)

Initial work for workflows DotNET SDK

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Beefed up the workflows example program and added in statestore functionality

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Addressing a bunch of review comments

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Updates to readme and demo for workflows

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Changed webapp to console app

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Update DurableTask SDK dependency to get ARM64 compatibility (#1024)

* Update DurableTask SDK dependency to get ARM64 compatibility

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

* Fix issue with gRPC address override behavior

Signed-off-by: Chris Gillum <cgillum@microsoft.com>
Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Remove Web APIs and web dependencies

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Renaming WorkflowWebApp to WorkflowConsoleApp

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Various updates to the sample app

- Replaced DaprClient with WorkflowEngineClient
- Removed unused etag logic
- Fixed incorrect usage of certain model types
- Cleaned up logs and console output
- Simplified program loop
- Cleaned up console output and added some coloring
- Added error handling in the console interactions
- Various other tweaks/simplifications/enhancements

Signed-off-by: Chris Gillum <cgillum@microsoft.com>
Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Updates to README and demo http commands

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Make README copy/paste-able and some other minor tweaks

Signed-off-by: Chris Gillum <cgillum@microsoft.com>
Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Adding in Paul's devcontainer work

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* More README touch-ups

Signed-off-by: Chris Gillum <cgillum@microsoft.com>
Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* [docs] Add workflows to .NET client doc (#1019)

* add workflows to client page

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Updating workflows readme and example

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* Fixing README for letting users know which .NET is needed

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

* moving using statements above the namespace

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>

---------

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>
Signed-off-by: Chris Gillum <cgillum@microsoft.com>
Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
Co-authored-by: Ryan Lettieri <ryanLettieri@microsoft.com>
Co-authored-by: Chris Gillum <cgillum@microsoft.com>
Co-authored-by: Hannah Hunter <94493363+hhunter-ms@users.noreply.github.com>
2023-02-10 11:55:37 -08:00
Hannah Hunter bc3ec80e4a
[docs] Add workflows to .NET client doc (#1019)
* add workflows to client page

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
2023-02-08 13:38:45 -08:00
Chris Gillum 22ac4c5145
Update DurableTask SDK dependency to get ARM64 compatibility (#1024)
* Update DurableTask SDK dependency to get ARM64 compatibility

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

* Fix issue with gRPC address override behavior

Signed-off-by: Chris Gillum <cgillum@microsoft.com>
2023-02-03 13:43:10 -08:00
Ryan Lettieri 152d190709
Workflow Management - Initial Methods (#1003)
Initial work for workflows DotNET SDK

Signed-off-by: Ryan Lettieri <ryanLettieri@microsoft.com>
2023-01-30 16:12:00 -08:00
Yash Nisar 6e77f12a39
Add support for repetition and ISO 8601 for reminders (#974)
Signed-off-by: Yash Nisar <yashnisar@microsoft.com>

Signed-off-by: Yash Nisar <yashnisar@microsoft.com>
2023-01-26 20:13:42 -08:00
Yash Nisar 1605ecd90e
Implement Bulk Publish functionality (#1001)
Closes https://github.com/dapr/dotnet-sdk/issues/958

Signed-off-by: Yash Nisar <yashnisar@microsoft.com>

Signed-off-by: Yash Nisar <yashnisar@microsoft.com>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2023-01-26 11:34:09 -08:00
halspang 76d4b682ec
Add net7 to testing matrix (#1005)
Signed-off-by: halspang <halspang@microsoft.com>

Signed-off-by: halspang <halspang@microsoft.com>
2023-01-26 11:00:43 -08:00
Chris Gillum 389de69180
Additional API surface area for Dapr Workflow authoring SDK (#1012)
* Additional API surface area

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

* PR feedback

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

* Environment variable configuration

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

* Fix .NET TFMs and complete the README.md contents

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

Signed-off-by: Chris Gillum <cgillum@microsoft.com>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2023-01-24 15:41:56 -08:00
halspang 5a7e59fce3
Remove debug statement from configuration example (#949)
Signed-off-by: Hal Spang <halspang@microsoft.com>
2023-01-23 12:04:22 -08:00
halspang b8766b9df5
Add method to publish without client serialization (#1010)
This commit adds the ability to publish raw bytes instead of using
the serialization that is built into the client.

https://github.com/dapr/dotnet-sdk/issues/718

Signed-off-by: halspang <halspang@microsoft.com>
2023-01-23 11:41:37 -08:00
Hannah Hunter 117c5ad1cb
Restructure .NET sdk landing page (#1006)
* restructure .net index page

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>

* updates to the landing page per Mark/Hal/Nick review

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>

* remove version

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
2023-01-20 16:35:09 -08:00
Tiago Alves Macambira 2aa4806c44
Workflow Authoring: initial methods (#981)
* Initial workflow sdk implementation

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Dapr Workflow initial methods for dotnet-sdk

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Handled mistake in the workflow name

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Added common license header to .cs files

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Changed namespace to Dapr.Workflow

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Addressed docs related review comments

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Reverted few changes to avoid compile time error

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Examples changes

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Added readonly dictionary

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Added .csproj to sln file with few minor comments

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Change nuget dependency and update folder structure

This commit re-adds commit d5b9189da5 but with DCO.

Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>

* Update Durable Task SDK version & simplify example

Signed-off-by: Chris Gillum <cgillum@microsoft.com>

* Addresses some PR comments.

* Rename ActivityContext to WorkflowActivityContext
* Change example webapp port away from 8080x

Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>

* Addressing review comments.

* Rename workflow and activity in example to be more meangniful
* Add parameter documentation to some methods
* Use local project references when appropriate

Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>

* Adding more documentation

Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>

* Replaces custom AddSingletonIfNotPresent with std. TryAddSingleton

Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>

* Renames AddWorkflowsToRegistry to AddActivitiesToRegistry to better match what it does

Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>

* Add cancelation token overload for WorkflowContext.WaitForExternalEventAsync

Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>

* Renaming AddWorkflowsAndActivitiesToRegistry

Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>

* Defer launch URL and port to launchSettings.json

Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>
Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>
Signed-off-by: Chris Gillum <cgillum@microsoft.com>
Co-authored-by: Amulya Varote <amulyavarote@microsoft.com>
Co-authored-by: Chris Gillum <cgillum@microsoft.com>
2023-01-12 16:10:21 -08:00
amulyavarote ab5403ed01
Changed broken link in README (#980)
Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>
2022-11-04 13:28:19 -07:00
Yash Nisar 1efe1fa30b
Add support for Bulk State, i.e. SaveBulkStateAsync(...) method (#962)
* Add support for Bulk State, i.e. SaveBulkStateAsync

Closes https://github.com/dapr/dotnet-sdk/issues/785

Signed-off-by: Yash Nisar <yashnisar@microsoft.com>

* Update examples to include support for Bulk State

Closes https://github.com/dapr/dotnet-sdk/issues/963

Signed-off-by: Yash Nisar <yashnisar@microsoft.com>

Signed-off-by: Yash Nisar <yashnisar@microsoft.com>
2022-10-31 11:06:27 -07:00
amulyavarote 56017dd94a
Changed distributedLock example to consider a new default port number (#966)
* Changed distributedLock example to consider a new default port number

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Changes based on the review comments

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2022-10-24 13:10:46 -07:00
Hannah Hunter e87b9ad6ee
remove version flags per docs issue (#960)
Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
2022-10-17 10:39:16 -07:00
Alessandro (Ale) Segala 3224579c3e
Report user-agent with SDK version (#968)
Signed-off-by: ItalyPaleAle <43508+ItalyPaleAle@users.noreply.github.com>
2022-10-13 11:57:55 -07:00
Mark Fussell 52b82d7ce6
Fixed broken link reference
Signed-off-by: Mark Fussell <mfussell@microsoft.com>
2022-10-12 15:56:43 -07:00
saber-wang 01cdc89710
add metadata api (#947)
* feat: add metadata api
Signed-off-by: saberwang <saberwang@hotmail.com>

* Using HTTP API to get and set dapr metadata
Signed-off-by: saberwang <saberwang@hotmail.com>

* style
Signed-off-by: saberwang <saberwang@hotmail.com>

* using grpc to add metadata api
Signed-off-by: saberwang <saberwang@hotmail.com>

* style
Signed-off-by: saberwang <saberwang@hotmail.com>

Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2022-09-23 12:06:01 -07:00
Yash Nisar 37ed4987d8
Add dapr-bot support to assign issues (#951)
Closes https://github.com/dapr/dotnet-sdk/issues/933

Signed-off-by: Yash Nisar <yashnisar@microsoft.com>
2022-09-19 11:04:25 -07:00
amulyavarote 990139e5e3
Added actor method exception details docs (#950)
* Added actor method exception details docs

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Changes based on the review comments

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>
2022-09-15 17:40:02 -07:00
amulyavarote 5043b9f8c3
Configuration API changes to support dictionary type response (#943)
* Added config class changes

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Changed examples, extension files and tests to support dictionary

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Changes based on the review comments

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2022-09-13 15:10:46 -07:00
Hannah Hunter c260680f26
[Docs refresh] Actors section refresh (#918)
* grammar and readability to actors section

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>

* remove server section

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>

Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2022-09-13 13:10:09 -07:00
Yash Nisar efacff4f58
Change log level to information in pubsub examples (#942)
Fixes https://github.com/dapr/dotnet-sdk/issues/936

Signed-off-by: Yash Nisar <yashnisar@microsoft.com>

Signed-off-by: Yash Nisar <yashnisar@microsoft.com>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2022-09-01 14:06:50 -07:00
amulyavarote f874d60ca4
Added exception details to the actor invocation (#931)
Added exception details to the actor invocation

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>
2022-08-31 15:23:02 -07:00
saber-wang 0998b0dd4d
topicmetadata should allow adding empty strings (#940)
* topicmetadata should allow adding empty strings
Signed-off-by: saberwang <saberwang@hotmail.com>

* fix test errors
Signed-off-by: saberwang <saberwang@hotmail.com>
2022-08-29 11:42:17 -07:00
amulyavarote 2ab1b7cee0
Added new links to client folder in example (#938)
Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>
2022-08-25 15:48:41 -07:00
halspang a8095592a1
Add support for shutdown API and add client docs (#922)
This commit adds support for the shutdown API. It also adds docs for
that method and a few others which were missing from the docs.

https://github.com/dapr/dotnet-sdk/issues/914

Signed-off-by: Hal Spang <halspang@microsoft.com>
2022-08-23 09:14:32 -07:00
Yash Nisar e6ded69ca4
Add dead letter topic support (#929)
Closes https://github.com/dapr/dotnet-sdk/issues/897

Signed-off-by: Yash Nisar <yashnisar@microsoft.com>

Signed-off-by: Yash Nisar <yashnisar@microsoft.com>
2022-08-22 13:39:31 -07:00
dss539 62c1d72c41
Update dotnet-daprclient-usage.md (#930)
minor typo correction

Signed-off-by: dss539 <dss539@gmail.com>

Signed-off-by: dss539 <dss539@gmail.com>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2022-08-19 13:03:08 -07:00
Tiago Alves Macambira c8a2adea4b
Update SDK to reflect renaming on UnlockResponse.Status (#924)
PR dapr/dapr#4989 (issue dapr/dapr#4988) updated the names of some
enums in `UnlockResponse.Status` ProtoBuff definition:

* `LOCK_UNEXIST` became `LOCK_DOES_NOT_EXIST `
* `LOCK_BELONG_TO_OTHERS`  became `LOCK_BELONGS_TO_OTHERS`

Code in clients SDKs needs to be updated to account for this modification.

This PR accomplishes this by updating:
1. the generated gRPC Protobuf client and
2. the SDK code and tests.

Fixes dapr/dotnet-sdk#921

Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>

Signed-off-by: Tiago Alves Macambira <tmacam@burocrata.org>
2022-08-17 13:18:11 -07:00
Marcos Candeia a57375f343
Upgrade grpc.tools version to 2.47.0 for supporting arm64 architecture (#920)
* Upgrade grpc.tools version to 2.47.0 for supporting arm64 architecture

Signed-off-by: Marcos Candeia <marrcooos@gmail.com>

* Upgrade Grpc.* packages to version 2.47.0

Signed-off-by: Marcos Candeia <marrcooos@gmail.com>

Signed-off-by: Marcos Candeia <marrcooos@gmail.com>
2022-08-10 12:43:50 -07:00
Marcos Candeia 815d5030a8
FIX Allow actor healthz endpoint are now always AllowAnonymous (#923)
Signed-off-by: Marcos Candeia <marrcooos@gmail.com>

Signed-off-by: Marcos Candeia <marrcooos@gmail.com>
2022-08-10 12:31:40 -07:00
halspang 0c4a3362da
Update Dapr and CLI to 1.8 (#893)
Signed-off-by: Hal Spang <halspang@microsoft.com>
2022-08-09 16:47:47 -07:00
halspang 8bc7e90194
Add Actor Reminder/Timer TTL support (#912)
Add Actor Reminder/Timer TTL support

This commit adds the TTL field to Actor reminders/timers. This allows
reminders and timers to expire after a given TimeSpan instead of
having to be manually deleted.

https://github.com/dapr/dotnet-sdk/issues/788

Signed-off-by: Hal Spang <halspang@microsoft.com>
2022-08-03 11:56:53 -07:00
saber-wang e58b1de56a
Fix the problem of determining whether there is a MetadataSeparator error (#900)
* add  original topic metadata support
Signed-off-by: saberwang <saberwang@hotmail.com>

* Add topicmetadata sample
Signed-off-by: saberwang <saberwang@hotmail.com>

* fix: v2 route metadata acquisition error
Signed-off-by: saberwang <saberwang@hotmail.com>

* feat:  Support setting metadata separator
Signed-off-by: saberwang <saberwang@hotmail.com>

* chore: Note modification
Signed-off-by: saberwang <saberwang@hotmail.com>

* style:
Signed-off-by: saberwang <saberwang@hotmail.com>

* commit
Signed-off-by: saberwang <saberwang@hotmail.com>

* fix: Whether there is a problem of MetadataSeparator judgment error
Signed-off-by: saberwang <saberwang@hotmail.com>

* TopicAttribute.Metadataseparator default should be null
Signed-off-by: saberwang <saberwang@hotmail.com>

* formatting code
Signed-off-by: saberwang <saberwang@hotmail.com>

Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2022-07-20 08:32:33 -07:00
halspang d061164ec8
Add client docs for Configuration Subscribe API (#895)
Signed-off-by: Hal Spang <halspang@microsoft.com>
2022-07-05 16:17:45 -07:00
amulyavarote 016545ac0d
Added dotnet methods for Distributed Lock API (#886)
* Added dotnet methods for Distributed Lock API

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Changes based on the review comments

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Changes in examples to make them real world - based on the PR review

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Fixed application log statements

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Changes to implement IDisposable

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Changes based on the review comments

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Added a sample test case for TryLockResponse

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Changes based on the review comments - 2

Signed-off-by: Amulya Varote <amulyavarote@microsoft.com>

* Reworking the DistributedLock example

Signed-off-by: Hal Spang <halspang@microsoft.com>

Co-authored-by: Hal Spang <halspang@microsoft.com>
2022-06-29 10:23:37 -07:00
saber-wang 927daa48eb
add original topic metadata support (#876)
* add  original topic metadata support
Signed-off-by: saberwang <saberwang@hotmail.com>

* Add topicmetadata sample
Signed-off-by: saberwang <saberwang@hotmail.com>
2022-06-21 09:49:15 -07:00
halspang a4af2a4567
Add Fossa scan to the CI workflow (#889)
https://github.com/dapr/dotnet-sdk/issues/843

Signed-off-by: Hal Spang <halspang@microsoft.com>
2022-06-09 14:47:04 -07:00
halspang e4236c4c54
Add support for per type actor configuration (#870)
This commit allows different actor types to provide their own
configurations instead of relying on the top-level values. Any
value defined in them will be used instead of the top-level.
Anything that is left out will use the top-level or default if
it is undefined.

https://github.com/dapr/dotnet-sdk/issues/857

Signed-off-by: Hal Spang <halspang@microsoft.com>
2022-05-26 14:47:46 -07:00
halspang cda60cb382
Add Subscribe/Unsubscribe API support (#848)
Add Subscribe/Unsubscribe API support

This commit adds support for both the subscribe and unsubscribe
APIs for Darp's Configuration building block. The configuration can
now be exposed through the AspNet builder pattern or by making the
request directly with the DaprClient.

https://github.com/dapr/dotnet-sdk/issues/822

Signed-off-by: Hal Spang <halspang@microsoft.com>
2022-05-26 14:43:34 -07:00
Tequila Sunset 0046507076
Allow publishing cloud events directly (#868)
Signed-off-by: Sun Zhongfeng <suraciii@outlook.com>

Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2022-05-20 14:51:18 -07:00
听雨声 26518321f2
Fix Adds DaprClient in Dapr.AspNetCore from AddSingleton to TryAddSingleton (#867)
Signed-off-by: zhenlei520 <wangzhenlei520@gmail.com>
2022-05-17 10:44:53 -07:00
Zhiqiang Li ce1315fbbe
WithTopic extension method add overload (#864)
WithTopic add enableRawPayload overload method

Signed-off-by: stulzq <stulzq@qq.com>

Co-authored-by: Ryan Nowak <nowakra@gmail.com>
Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2022-05-17 10:41:18 -07:00
halspang 291f73758d
Upgrade dapr/cli used in e2e test workflow (#863)
Signed-off-by: Hal Spang <halspang@microsoft.com>
2022-04-25 08:54:42 -07:00
Jadyn 452ccad335
Fix App API token authentication (#836)
* Fix App API token authentication

Signed-off-by: Jadyn <jadyn.wong@live.com>

* Add e2e test for App API token authentication

Signed-off-by: Jadyn <jadyn.wong@live.com>

* Rename dapr api token

Signed-off-by: Jadyn <jadyn.wong@live.com>
2022-04-19 14:17:49 -07:00
Hannah Hunter bc4a52af91
typo fixes (#855)
Signed-off-by: Hannah Hunter <hannahhunter@microsoft.com>
2022-04-01 08:41:40 -07:00
halspang 3553899235
Update Google.Protobuf to 3.15 (#850)
Signed-off-by: Hal Spang <halspang@microsoft.com>
2022-03-23 10:51:41 -07:00
halspang a6319dd4b6
Wait for sidecar in DaprSecretStoreConfiguration (#838)
The secret store configuration provider was trying to access Dapr
during the app startup. If the app started faster than Dapr, it would
get an error trying to access the secrets. This commit lets the
provider wait for the sidecar to come up before making any requests.
If the sidecar does not come up at all, we will still fail.

https://github.com/dapr/dotnet-sdk/issues/779

Signed-off-by: Hal Spang <halspang@microsoft.com>
2022-02-17 16:39:33 -08:00
Martin Björkström dca6106af7
Adds support for providing Actor type name during runtime. (#721)
* Adds support for providing Actor type name during runtime.

- Fixes #677

Signed-off-by: Martin Björkström <martin.bjorkstrom@gmail.com>

* Make ActorTypeInformation.TryGet(Type) and ActorTypeInformation.Get(Type) obsolete.

- Fix relevant code after obsoleting.

Signed-off-by: Martin Björkström <martin.bjorkstrom@gmail.com>
2022-02-15 11:01:45 -08:00
mumumi 52113a3fd2
Fix missing assignment (#824)
* Fix missing assignment

ActorHost.JsonSerializerOptions is always null.

Signed-off-by: mumumi <hjjixx@hotmail.com>

* Add test for custom json options

Signed-off-by: mumumi <hjjixx@hotmail.com>

Co-authored-by: halspang <70976921+halspang@users.noreply.github.com>
2022-01-28 09:15:38 -08:00
halspang a8acdea23f
Include .NET 5 in all builds and check test status (#826)
Signed-off-by: Hal Spang <halspang@microsoft.com>
2022-01-28 08:33:10 -08:00
halspang 8ba4234578
Update Parse Trx github action (#825)
Signed-off-by: Hal Spang <halspang@microsoft.com>
2022-01-27 16:56:49 -08:00
halspang 7690e98663
Add .NET 6 build targets for tests (#823)
https://github.com/dapr/dotnet-sdk/issues/794

Signed-off-by: Hal Spang <halspang@microsoft.com>
2022-01-26 08:59:20 -08:00
Mark Fussell b47c63ac14
Merge pull request #821 from halspang/query_docs
Add client example for Query API (Alpha)
2022-01-24 11:17:17 -08:00
Hal Spang aab8c95dfb Add client example for Query API (Alpha)
This commit adds a client example for the Query API. It also
marks the Configuration API as alpha.

Signed-off-by: Hal Spang <halspang@microsoft.com>
2022-01-24 11:03:41 -08:00
halspang 20ef37382c
Add documentation for GetConfiguration API (#818)
https://github.com/dapr/docs/issues/2094

Signed-off-by: Hal Spang <halspang@microsoft.com>
2022-01-21 16:15:09 -08:00
amulyavarote 596d725785
Changed application port number for actors example (#816)
* Changed application port number for actors example

* Modified readme for actors example

* Update README.md

Signed-off-by: Amulya Varote <amulyavarote@Amulyas-MacBook-Pro.local>

Co-authored-by: Amulya Varote <amulyavarote@Amulyas-MacBook-Pro.local>
2022-01-20 16:01:01 -08:00
halspang 764b4d7674
Fix issue where state did not reset on actor error (#789)
When an actor call fails, it is imperative that the state is reset.
In the remoting path, we were catching the exception and returning
an error response instead of propagating the exception. Without this,
the error path was never triggered. This allowed for state from
failed requests to persist on subsequent requests.

https://github.com/dapr/dotnet-sdk/issues/762

Signed-off-by: Hal Spang <halspang@microsoft.com>
2022-01-13 09:01:31 -08:00
halspang d43de2b043
Add support for Query API (#810)
This commit adds methods to the DaprClient to call the new Query API.
Currently, a raw query string is provided to the API. The API is
still in the alpha stage which may cause shifts in how the API works.
This should not effect how the SDK exposes the call, but may change
the underlying semantics.

https://github.com/dapr/dotnet-sdk/issues/777

Signed-off-by: Hal Spang <halspang@microsoft.com>

Co-authored-by: Ryan Nowak <nowakra@gmail.com>
2022-01-12 17:50:06 -08:00
halspang f5169cbe5f
Add support for the GetConfiguration API (#812)
This commit adds support for the GetConfiguration API. This is an
alpha API and may be subject to change. This commit also does not
cover the Subscribe API for Configurations.

Included is a simple example showing the usage of the Configuration
API.

https://github.com/dapr/dotnet-sdk/issues/787

Signed-off-by: Hal Spang <halspang@microsoft.com>
2022-01-12 17:07:48 -08:00
Will edd6b3db74
Add DCO requirements and updated code of conduct (#808)
Issue reference: dapr/docs#2039

Signed-off-by: Will <william.wl.tsai@gmail.com>
2022-01-06 10:35:50 -08:00
Mark Fussell 2ffbb113e7 fixed link
Signed-off-by: Mark Fussell <markfussell@gmail.com>
2021-12-28 15:31:59 -08:00
Mark Fussell d60eaf1c0e
Merge pull request #781 from fjvela/fix-link-to-docker
Fix ref to self hosted with docker
2021-12-28 11:45:05 -08:00
Mark Fussell 1e563ad38e
Merge branch 'master' into fix-link-to-docker 2021-12-28 11:31:02 -08:00
Dmitry Shmulevich 0c9d6a45c8
replaced license headers (#802)
Signed-off-by: Dmitry Shmulevich <dmitry.shmulevich@gmail.com>
2021-12-10 13:39:06 -08:00
halspang 8a38c292a0
Update Dapr Protos (#801)
This commit includes the copied files from dapr/dapr. These are used
to generate the gRPC client. Included in the update are:
 - Configuration API
 - Query API

Signed-off-by: Hal Spang <halspang@microsoft.com>
2021-12-10 11:09:15 -08:00
Javier Vela a0b514a2cb
Merge branch 'master' into fix-link-to-docker 2021-11-17 19:45:58 +01:00
Javier Vela 4817b13b5d Fix ref to self hosted with docker 2021-11-16 16:16:29 +01:00
halspang cc1b097991
Allow multiple topics to call the same endpoint (#763)
* Allow multiple topics to call the same endpoint

Using the WithTopic builder pattern allows you to specify multiple
topics that route to a single endpoint. Given the topics are unique,
this should be a valid case.

This change allows for a single endpoint to bind to multiple topics.
Note that this can only be done via the EndpointBuilder and not the
TopicAttribute.

https://github.com/dapr/dotnet-sdk/issues/715

* Let TopicAttribute to be specified multiple times

The endpoint builder allowed for multiple WithTopic calls so the
attribute should match that behavior.
2021-10-26 13:42:28 -07:00
halspang f3258632f4
Add support for gRPC proxying (#755)
This commit adds a gRPC interceptor which adds the necessary
headers for gRPC proxying to outgoing requests. This will allow
custom gRPC services to be invoked through the Dapr sidecar.

https://github.com/dapr/dotnet-sdk/issues/741

Co-authored-by: Ryan Nowak <nowakra@gmail.com>
2021-10-19 14:08:29 -07:00
Whwlsfb a01a9d61b6
Fix StateManager can't get dapr-api-token header. (#768)
When "dapr_api_token" is specified in the environment variable, actor.statemanager cannot correctly set "dapr-api-token" in the request header。

Co-authored-by: Ryan Nowak <nowakra@gmail.com>
2021-10-19 13:34:59 -07:00
halspang 839acaf877
Fix FromTopic route binding error (#770)
https://github.com/dapr/dotnet-sdk/issues/706
2021-10-19 13:13:29 -07:00
Michael Robertson fc54f21d00
- Added null-conditional operator to StateEntryApplicationModelProvider.OnProvidersExecuted when checking BindingSource to prevent startup null reference exceptions in certain implementations. (#765)
- Added null check and throws unit tests for StateEntryApplicationModelProvider
2021-10-13 16:53:22 -07:00
Phil Kedy 75bdb8ce2f
Fixing falsely logged default subscription message (#761) 2021-10-04 15:40:53 -07:00
Federico Bridger 1acd372ae2
Fixing problem with IIS Express not allowing Applications to subscribe to events (#754)
Co-authored-by: Federico.Bridger <Federico.Bridger@endava.com>
2021-09-28 13:50:49 -07:00
Christophe GIGAX a23aebe669
Add unit tests for InvokeBinding method (#751)
Co-authored-by: Christophe Gigax <christophe.gigax@codit.eu>
Co-authored-by: Ryan Nowak <nowakra@gmail.com>
2021-09-16 15:41:04 -07:00
鬼谷子 8e4b35e0b7
Fix preview 7 dapr config (#738)
* feat: support Minimal APIs

* feat: support minimal api add actor

* feat: actor support minimal API

* fix: preview 7 dapr config

* chore: remove unused namespace

* chore: rollback

* chore: remove preview 6 fix

* feat: add MapDaprConfigEndpoint test

* chore: remove comment

Co-authored-by: Ryan Nowak <nowakra@gmail.com>
2021-09-16 15:35:46 -07:00
760 changed files with 44214 additions and 5838 deletions

29
.devcontainer/Dockerfile Normal file
View File

@ -0,0 +1,29 @@
#
# Copyright 2021 The Dapr Authors
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
ARG VARIANT=bullseye
FROM mcr.microsoft.com/vscode/devcontainers/dotnet:dev-7.0-bullseye
# Install minikube
RUN MINIKUBE_URL="https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64" \
&& sudo curl -sSL -o /usr/local/bin/minikube "${MINIKUBE_URL}" \
&& sudo chmod 0755 /usr/local/bin/minikube \
&& MINIKUBE_SHA256=$(curl -sSL "${MINIKUBE_URL}.sha256") \
&& echo "${MINIKUBE_SHA256} */usr/local/bin/minikube" | sha256sum -c -
# Install Dapr CLI
RUN wget -q https://raw.githubusercontent.com/dapr/cli/master/install/install.sh -O - | /bin/bash
# Install Azure Dev CLI
RUN curl -fsSL https://aka.ms/install-azd.sh | bash

View File

@ -0,0 +1,55 @@
{
"name": "Azure Developer CLI",
"build": {
"dockerfile": "Dockerfile",
"args": {
"VARIANT": "bullseye"
}
},
"features": {
"ghcr.io/devcontainers/features/azure-cli:1": {
"version": "2.38"
},
"ghcr.io/devcontainers/features/docker-in-docker": {
"version": "latest"
},
"ghcr.io/devcontainers/features/dotnet": {
"version": "8.0",
"additionalVersions": [
"6.0",
"7.0"
]
},
"ghcr.io/devcontainers/features/github-cli:1": {
"version": "2"
},
"ghcr.io/devcontainers/features/node:1": {
"version": "16",
"nodeGypDependencies": false
}
},
"extensions": [
"ms-azuretools.azure-dev",
"ms-azuretools.vscode-bicep",
"ms-azuretools.vscode-docker",
"ms-vscode.vscode-node-azure-pack",
"ms-dotnettools.csharp",
"ms-dotnettools.vscode-dotnet-runtime",
"ms-azuretools.vscode-dapr",
"GitHub.copilot",
"ms-dotnettools.csdevkit"
],
"forwardPorts": [
3000,
3100,
3500,
3501,
5000,
5007
],
"postCreateCommand": "chmod +x .devcontainer/localinit.sh && .devcontainer/localinit.sh",
"remoteUser": "vscode",
"hostRequirements": {
"memory": "8gb"
}
}

9
.devcontainer/localinit.sh Executable file
View File

@ -0,0 +1,9 @@
# install Azure CLI extension for Container Apps
az config set extension.use_dynamic_install=yes_without_prompt
az extension add --name containerapp --yes
# install Node.js and NPM LTS
nvm install v18.12.1
# initialize Dapr
dapr init --runtime-version=1.14.0

View File

@ -22,6 +22,7 @@ charset = utf-8-bom
# Organize usings
dotnet_sort_system_directives_first = true
dotnet_separate_import_directive_groups = false
csharp_using_directive_placement = outside_namespace
# this. preferences
dotnet_style_qualification_for_field = false:silent

View File

@ -1,5 +1,5 @@
---
name: Feature Request
name: Discussion
about: Start a discussion for Dapr
title: ''
labels: kind/discussion

6
.github/holopin.yml vendored Normal file
View File

@ -0,0 +1,6 @@
organization: dapr
defaultSticker: clrqfdv4x24910fl5n4iwu5oa
stickers:
-
id: clrqfdv4x24910fl5n4iwu5oa
alias: sdk-badge

View File

@ -1,6 +1,14 @@
# ------------------------------------------------------------
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# Copyright 2021 The Dapr Authors
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ------------------------------------------------------------
# This script parses release version from Git tag and set the parsed version to

76
.github/workflows/dapr-bot.yml vendored Normal file
View File

@ -0,0 +1,76 @@
name: dapr-bot
on:
issue_comment: {types: created}
jobs:
daprbot:
name: bot-processor
runs-on: ubuntu-latest
steps:
- name: Comment analyzer
uses: actions/github-script@v1
with:
github-token: ${{secrets.DAPR_BOT_TOKEN}}
script: |
// list of owner who can control dapr-bot workflow
const owners = [
"yaron2",
"berndverst",
"artursouza",
"mukundansundar",
"halspang",
"tanvigour",
"pkedy",
"amulyavarote",
"daixiang0",
"ItalyPaleAle",
"jjcollinge",
"pravinpushkar",
"shivamkm07",
"shubham1172",
"skyao",
"msfussell",
"Taction",
"RyanLettieri",
"DeepanshuA",
"yash-nisar",
"addjuarez",
"tmacam",
];
const payload = context.payload;
const issue = context.issue;
const isFromPulls = !!payload.issue.pull_request;
const commentBody = payload.comment.body;
if (!isFromPulls && commentBody && commentBody.indexOf("/assign") == 0) {
if (!issue.assignees || issue.assignees.length === 0) {
await github.issues.addAssignees({
owner: issue.owner,
repo: issue.repo,
issue_number: issue.number,
assignees: [context.actor],
})
}
return;
}
// actions above this check are enabled for everyone.
if (owners.indexOf(context.actor) < 0) {
return;
}
if (commentBody && commentBody.indexOf("/make-me-laugh") == 0) {
const result = await github.request("https://official-joke-api.appspot.com/random_joke");
jokedata = result.data;
joke = "I have a bad feeling about this.";
if (jokedata && jokedata.setup && jokedata.punchline) {
joke = `${jokedata.setup} - ${jokedata.punchline}`;
}
await github.issues.createComment({
owner: issue.owner,
repo: issue.repo,
issue_number: issue.number,
body: joke,
});
return;
}

46
.github/workflows/fossa.yml vendored Normal file
View File

@ -0,0 +1,46 @@
#
# Copyright 2021 The Dapr Authors
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
name: fossa
on:
push:
branches:
- master
- release-*
tags:
- v*
pull_request:
branches:
- master
- release-*
workflow_dispatch: {}
jobs:
fossa-scan:
if: github.repository_owner == 'dapr' # FOSSA is not intended to run on forks.
runs-on: ubuntu-latest
env:
FOSSA_API_KEY: b88e1f4287c3108c8751bf106fb46db6 # This is a push-only token that is safe to be exposed.
steps:
- name: "Checkout code"
uses: actions/checkout@v2
- name: "Run FOSSA Scan"
uses: fossas/fossa-action@main # Use a specific version if locking is preferred
with:
api-key: ${{ env.FOSSA_API_KEY }}
- name: "Run FOSSA Test"
uses: fossas/fossa-action@main # Use a specific version if locking is preferred
with:
api-key: ${{ env.FOSSA_API_KEY }}
run-tests: true

View File

@ -18,38 +18,43 @@ jobs:
name: run integration tests
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
dotnet-version: ['3.1', '5.0']
dotnet-version: ['6.0', '7.0', '8.0', '9.0']
include:
- dotnet-version: '3.1'
install-3: true
display-name: '.NET Core 3.1'
framework: 'netcoreapp3.1'
prefix: 'netcoreapp31'
- dotnet-version: '5.0'
install-3: false
display-name: '.NET 5.0'
framework: 'net5'
prefix: 'net5'
- dotnet-version: '6.0'
display-name: '.NET 6.0'
framework: 'net6'
prefix: 'net6'
install-version: '6.0.x'
- dotnet-version: '7.0'
display-name: '.NET 7.0'
framework: 'net7'
prefix: 'net7'
install-version: '7.0.x'
- dotnet-version: '8.0'
display-name: '.NET 8.0'
framework: 'net8'
prefix: 'net8'
install-version: '8.0.x'
- dotnet-version: '9.0'
display-name: '.NET 9.0'
framework: 'net9'
prefix: 'net9'
install-version: '9.0.x'
env:
NUPKG_OUTDIR: bin/Release/nugets
GOVER: 1.15.0
GOVER: 1.20.3
GOOS: linux
GOARCH: amd64
GOPROXY: https://proxy.golang.org
DAPR_CLI_VER: 1.2.0
DAPR_RUNTIME_VER: 1.2.1
DAPR_INSTALL_URL: https://raw.githubusercontent.com/dapr/cli/3dacfb672d55f1436c249057aaebbe597e1066f3/install/install.sh
DAPR_CLI_VER: 1.15.0
DAPR_RUNTIME_VER: 1.15.3
DAPR_INSTALL_URL: https://raw.githubusercontent.com/dapr/cli/release-1.14/install/install.sh
DAPR_CLI_REF: ''
DAPR_REF: ''
steps:
- name: Set up Dapr CLI
run: wget -q ${{ env.DAPR_INSTALL_URL }} -O - | /bin/bash -s ${{ env.DAPR_CLI_VER }}
- name: Set up Go ${{ env.GOVER }}
if: env.DAPR_REF != '' || env.DAPR_CLI_REF != ''
uses: actions/setup-go@v2
with:
go-version: ${{ env.GOVER }}
- name: Checkout Dapr CLI repo to override dapr command.
uses: actions/checkout@v2
if: env.DAPR_CLI_REF != ''
@ -64,6 +69,16 @@ jobs:
repository: dapr/dapr
ref: ${{ env.DAPR_REF }}
path: dapr
- name: Set up Go from dapr/go.mod
if: env.DAPR_REF != ''
uses: actions/setup-go@v3
with:
go-version-file: "dapr/go.mod"
- name: Set up Go from cli/go.mod
if: env.DAPR_REF == '' && env.DAPR_CLI_REF != ''
uses: actions/setup-go@v3
with:
go-version-file: "cli/go.mod"
- name: Build and override dapr cli with referenced commit.
if: env.DAPR_CLI_REF != ''
run: |
@ -92,29 +107,28 @@ jobs:
- uses: actions/checkout@v1
- name: Parse release version
run: python ./.github/scripts/get_release_version.py
- name: Install Local kafka using docker-compose
run: |
docker-compose -f test/Dapr.E2E.Test/deploy/local-test-kafka.yml up -d
docker ps
- name: Install Local Hashicorp Vault using docker-compose
run: |
docker-compose -f test/Dapr.E2E.Test/deploy/local-test-vault.yml up -d
docker ps
- name: Setup Vault's test token
run: echo myroot > /tmp/.hashicorp_vault_token
- name: Setup .NET Core 3.1
uses: actions/setup-dotnet@v1
if: matrix.install-3
- name: Setup ${{ matrix.display-name }}
uses: actions/setup-dotnet@v3
with:
dotnet-version: 3.1.x
- name: Setup .NET 5.0
uses: actions/setup-dotnet@v1
dotnet-version: ${{ matrix.install-version }}
dotnet-quality: 'ga' # Prefer a GA release, but use the RC if not available
- name: Setup .NET 8 (required)
uses: actions/setup-dotnet@v3
if: ${{ matrix.install-version != '8.0.x' }}
with:
dotnet-version: 5.0.x
dotnet-version: '8.0.x'
dotnet-quality: 'ga'
- name: Setup .NET 9 (required)
uses: actions/setup-dotnet@v3
if: ${{ matrix.install-version != '9.0.x' }}
with:
dotnet-version: '9.0.x'
dotnet-quality: 'ga'
- name: Build
# disable deterministic builds, just for test run. Deterministic builds break coverage for some reason
run: dotnet build --configuration release /p:GITHUB_ACTIONS=false
- name: Run Test
- name: Run General Tests
id: tests
continue-on-error: true # proceed if tests fail, the report step will report the failure with more details.
run: |
dotnet test ${{ github.workspace }}/test/Dapr.E2E.Test/Dapr.E2E.Test.csproj \
@ -128,6 +142,25 @@ jobs:
/p:CollectCoverage=true \
/p:CoverletOutputFormat=opencover \
/p:GITHUB_ACTIONS=false
- name: Run Generators Tests
id: generator-tests
continue-on-error: true # proceed if tests fail, the report step will report the failure with more details.
run: |
dotnet test ${{ github.workspace }}/test/Dapr.E2E.Test.Actors.Generators/Dapr.E2E.Test.Actors.Generators.csproj \
--configuration Release \
--framework ${{ matrix.framework }} \
--no-build \
--no-restore \
--logger "trx;LogFilePrefix=${{ matrix.prefix }}" \
--logger "GitHubActions;report-warnings=false" \
--logger "console;verbosity=detailed" \
--results-directory "${{ github.workspace }}/TestResults" \
/p:CollectCoverage=true \
/p:CoverletOutputFormat=opencover \
/p:GITHUB_ACTIONS=false
- name: Check test failure in PR
if: github.event_name == 'pull_request' && (steps.tests.outcome != 'success' || steps.generator-tests.outcome != 'success')
run: exit 1
- name: Upload test coverage
uses: codecov/codecov-action@v1
with:

View File

@ -24,15 +24,16 @@ jobs:
- name: Parse release version
run: python ./.github/scripts/get_release_version.py
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v3
with:
dotnet-version: 5.0.x
dotnet-version: 9.0.x
dotnet-quality: 'ga'
- name: Build
run: dotnet build --configuration release
- name: Generate Packages
run: dotnet pack --configuration release
- name: Upload packages
uses: actions/upload-artifact@master
uses: actions/upload-artifact@v4
with:
name: packages
path: ${{ env.NUPKG_OUTDIR }}
@ -41,37 +42,57 @@ jobs:
name: Test .NET ${{ matrix.dotnet-version }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
dotnet-version: ['3.1', '5.0']
dotnet-version: ['6.0', '7.0', '8.0', '9.0']
include:
- dotnet-version: '3.1'
install-3: true
display-name: '.NET Core 3.1'
framework: 'netcoreapp3.1'
prefix: 'netcoreapp31'
- dotnet-version: '5.0'
install-3: false
display-name: '.NET 5.0'
framework: 'net5'
prefix: 'net5'
- dotnet-version: '6.0'
display-name: '.NET 6.0'
framework: 'net6'
prefix: 'net6'
install-version: '6.0.x'
- dotnet-version: '7.0'
display-name: '.NET 7.0'
framework: 'net7'
prefix: 'net7'
install-version: '7.0.x'
- dotnet-version: '8.0'
display-name: '.NET 8.0'
framework: 'net8'
prefix: 'net8'
install-version: '8.0.x'
- dotnet-version: '9.0'
display-name: '.NET 9.0'
framework: 'net9'
prefix: 'net9'
install-version: '9.0.x'
steps:
- uses: actions/checkout@v1
- name: Parse release version
run: python ./.github/scripts/get_release_version.py
- name: Setup .NET Core 3.1
uses: actions/setup-dotnet@v1
if: matrix.install-3
- name: Setup ${{ matrix.display-name }}
uses: actions/setup-dotnet@v3
with:
dotnet-version: 3.1.x
- name: Setup .NET 5.0
uses: actions/setup-dotnet@v1
dotnet-version: ${{ matrix.install-version }}
dotnet-quality: 'ga' # Prefer a GA release, but use the RC if not available
- name: Setup .NET 8 (required)
uses: actions/setup-dotnet@v3
if: ${{ matrix.install-version != '8.0.x' }}
with:
dotnet-version: 5.0.x
dotnet-version: '8.0.x'
dotnet-quality: 'ga'
- name: Setup .NET 9 (required)
uses: actions/setup-dotnet@v3
if: ${{ matrix.install-version != '9.0.x' }}
with:
dotnet-version: '9.0.x'
dotnet-quality: 'ga'
- name: Build
# disable deterministic builds, just for test run. Deterministic builds break coverage for some reason
run: dotnet build --configuration release /p:GITHUB_ACTIONS=false
- name: Test
continue-on-error: true # proceed if tests fail, the report step will report the failure with more details.
id: tests
continue-on-error: true # proceed if tests fail to allow for the report generation in master or next step failure in PR
run: |
dotnet test \
--configuration release \
@ -85,12 +106,15 @@ jobs:
/p:CollectCoverage=true \
/p:CoverletOutputFormat=opencover \
/p:GITHUB_ACTIONS=false
- name: Check test failure in PR
if: github.event_name == 'pull_request' && steps.tests.outcome != 'success'
run: exit 1
- name: Upload test coverage
uses: codecov/codecov-action@v1
with:
flags: ${{ matrix.framework }}
- name: Parse Trx files
uses: NasAmin/trx-parser@v0.1.0
uses: NasAmin/trx-parser@v0.2.0
id: trx-parser
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository # does not work on PRs from forks
with:
@ -104,7 +128,7 @@ jobs:
if: startswith(github.ref, 'refs/tags/v') && !(endsWith(github.ref, '-rc') || endsWith(github.ref, '-dev') || endsWith(github.ref, '-prerelease'))
steps:
- name: Download release artifacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v4
with:
name: packages
path: packages

11
.gitignore vendored
View File

@ -91,7 +91,16 @@ bld/
# VS Code
.vscode/
# Jetbrains
.idea/
# coverlet code coverage results
coverage.json
.fake
.ionide
.ionide
# Examples bloat
examples/**/tmp
# MacOS
**/.DS_Store

View File

@ -2,19 +2,13 @@
Thank you for your interest in Dapr!
This project welcomes contributions and suggestions. Most contributions require you to
agree to a Contributor License Agreement (CLA) declaring that you have the right to,
and actually do, grant us the rights to use your contribution.
This project welcomes contributions and suggestions. Most contributions require you to signoff on your commits via
the Developer Certificate of Origin (DCO). When you submit a pull request, a DCO-bot will automatically determine
whether you need to provide signoff for your commit. Please follow the instructions provided by DCO-bot, as pull
requests cannot be merged until the author(s) have provided signoff to fulfill the DCO requirement.
You may find more information on the DCO requirements [below](#developer-certificate-of-origin-signing-your-work).
For details, visit https://cla.microsoft.com.
When you submit a pull request, a CLA-bot will automatically determine whether you need
to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the
instructions provided by the bot. You will only need to do this once across all repositories using our CLA.
This project has adopted the Microsoft Open Source Code of Conduct.
For more information see the Code of Conduct FAQ
or contact opencode@microsoft.com with any additional questions or comments.
This project has adopted the [Contributor Covenant Code of Conduct](https://github.com/dapr/community/blob/master/CODE-OF-CONDUCT.md).
Contributions come in many forms: submitting issues, writing code, participating in discussions and community calls.
@ -72,6 +66,47 @@ All contributions come through pull requests. To submit a proposed change, we re
A good way to communicate before investing too much time is to create a "Work-in-progress" PR and share it with your reviewers. The standard way of doing this is to add a "[WIP]" prefix in your PR's title and assign the **do-not-merge** label. This will let people looking at your PR know that it is not well baked yet.
### Developer Certificate of Origin: Signing your work
#### Every commit needs to be signed
The Developer Certificate of Origin (DCO) is a lightweight way for contributors to certify that they wrote or otherwise have the right to submit the code they are contributing to the project. Here is the full text of the [DCO](https://developercertificate.org/), reformatted for readability:
```
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or
(b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or
(c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it.
(d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved.
```
Contributors sign-off that they adhere to these requirements by adding a `Signed-off-by` line to commit messages.
```
This is my commit message
Signed-off-by: Random J Developer <random@developer.example.org>
```
Git even has a `-s` command line option to append this automatically to your commit message:
```
$ git commit -s -m 'This is my commit message'
```
Each Pull Request is checked whether or not commits in a Pull Request do contain a valid Signed-off-by line.
#### I didn't sign my commit, now what?!
No worries - You can easily replay your changes, sign them and force push them!
```
git checkout <branch-name>
git commit --amend --no-edit --signoff
git push --force-with-lease <remote-name> <branch-name>
```
### Use of Third-party code
- All third-party code must be placed in the `vendor/` folder.
@ -87,4 +122,14 @@ A non-exclusive list of code that must be places in `vendor/`:
## Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
This project has adopted the [Contributor Covenant Code of Conduct](https://github.com/dapr/community/blob/master/CODE-OF-CONDUCT.md)
## GitHub Dapr Bot Commands
Checkout the [daprbot documentation](https://docs.dapr.io/contributing/daprbot/) for Github commands you can run in this repo for common tasks. For example, you can comment `/assign` on an issue to assign it to yourself.

52
Directory.Packages.props Normal file
View File

@ -0,0 +1,52 @@
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="BenchmarkDotNet" Version="0.14.0" />
<PackageVersion Include="coverlet.collector" Version="6.0.2" />
<PackageVersion Include="coverlet.msbuild" Version="6.0.2" />
<PackageVersion Include="GitHubActionsTestLogger" Version="1.1.2" />
<PackageVersion Include="Google.Api.CommonProtos" Version="2.2.0" />
<PackageVersion Include="Google.Protobuf" Version="3.30.2" />
<PackageVersion Include="Grpc.AspNetCore" Version="2.71.0" />
<PackageVersion Include="Grpc.Core.Testing" Version="2.46.6" />
<PackageVersion Include="Grpc.Net.Client" Version="2.71.0" />
<PackageVersion Include="Grpc.Net.ClientFactory" Version="2.71.0" />
<PackageVersion Include="Grpc.Tools" Version="2.71.0" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.35" />
<PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="6.0.35" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="4.8.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing" Version="1.1.2" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing.XUnit" Version="1.1.2" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.8.0" />
<PackageVersion Include="Microsoft.DurableTask.Client.Grpc" Version="1.10.0" />
<PackageVersion Include="Microsoft.DurableTask.Worker.Grpc" Version="1.10.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="6.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.4" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="6.0.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
<PackageVersion Include="MinVer" Version="2.3.0" />
<PackageVersion Include="Moq" Version="4.20.72" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="protobuf-net.Grpc.AspNetCore" Version="1.2.2" />
<PackageVersion Include="Serilog.AspNetCore" Version="6.1.0" />
<PackageVersion Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageVersion Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageVersion Include="Shouldly" Version="4.2.1" />
<PackageVersion Include="System.Formats.Asn1" Version="6.0.1" />
<PackageVersion Include="System.Text.Json" Version="6.0.10" />
<PackageVersion Include="xunit" Version="2.9.2" />
<PackageVersion Include="xunit.extensibility.core" Version="2.9.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>
</Project>

217
LICENSE
View File

@ -1,21 +1,204 @@
Copyright (c) Microsoft Corporation.
MIT License
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
1. Definitions.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2021 The Dapr Authors.
and others that have contributed code to the public domain.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,8 +1,6 @@
# Dapr SDK for .NET
[![Build Status](https://github.com/dapr/dotnet-sdk/workflows/build/badge.svg)](https://github.com/dapr/dotnet-sdk/actions?workflow=build)
[![codecov](https://codecov.io/gh/dapr/dotnet-sdk/branch/master/graph/badge.svg)](https://codecov.io/gh/dapr/dotnet-sdk)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![NuGet Version](https://img.shields.io/nuget/v/Dapr.Client?logo=nuget&label=Latest%20version&style=flat)](https://www.nuget.org/packages/Dapr.Client) [![NuGet Downloads](https://img.shields.io/nuget/dt/Dapr.Client?style=flat&logo=nuget&label=Downloads)](https://www.nuget.org/packages/Dapr.Client) [![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/dapr/dotnet-sdk/.github%2Fworkflows%2Fsdk_build.yml?branch=master&label=Build&logo=github)](https://github.com/dapr/dotnet-sdk/actions/workflows/sdk_build.yml) [![codecov](https://codecov.io/gh/dapr/dotnet-sdk/branch/master/graph/badge.svg)](https://codecov.io/gh/dapr/dotnet-sdk) [![GitHub License](https://img.shields.io/github/license/dapr/dotnet-sdk?style=flat&label=License&logo=github)](https://github.com/dapr/dotnet-sdk/blob/master/LICENSE) [![GitHub issue custom search in repo](https://img.shields.io/github/issues-search/dapr/dotnet-sdk?query=type%3Aissue%20is%3Aopen%20label%3A%22good%20first%20issue%22&label=Good%20first%20issues&style=flat&logo=github)](https://github.com/dapr/dotnet-sdk/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) [![Discord](https://img.shields.io/discord/778680217417809931?label=Discord&style=flat&logo=discord)](http://bit.ly/dapr-discord) [![YouTube Channel Views](https://img.shields.io/youtube/channel/views/UCtpSQ9BLB_3EXdWAUQYwnRA?style=flat&label=YouTube%20views&logo=youtube)](https://youtube.com/@daprdev) [![X (formerly Twitter) Follow](https://img.shields.io/twitter/follow/daprdev?logo=x&style=flat)](https://twitter.com/daprdev)
Dapr SDK for .NET allows you to:
@ -47,12 +45,13 @@ This repo builds the following packages:
- Dapr.Actors
- Dapr.Actors.AspNetCore
- Dapr.Extensions.Configuration
- Dapr.Workflow
### Prerequisites
Each project is a normal C# project. At minimum, you need [.NET 5.0 SDK](https://dotnet.microsoft.com/download/dotnet/5.0) to build, test, and generate NuGet packages.
Each project is a normal C# project. At minimum, you need [.NET 6.0 SDK](https://dotnet.microsoft.com/download/dotnet/6.0) to build, test, and generate NuGet packages.
Also make sure to reference the [.NET SDK contribution guide](https://docs.dapr.io/contributing/dotnet-contributing/)
Also make sure to reference the [.NET SDK contribution guide](https://docs.dapr.io/contributing/sdk-contrib/dotnet-contributing/)
**macOS/Linux:**

311
all.sln
View File

@ -1,7 +1,6 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29318.209
# Visual Studio Version 17
VisualStudioVersion = 17.3.32929.385
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Actors", "src\Dapr.Actors\Dapr.Actors.csproj", "{C2DB4B64-B7C3-4FED-8753-C040F677C69A}"
EndProject
@ -15,11 +14,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Client", "src\Dapr.Cli
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.AspNetCore", "src\Dapr.AspNetCore\Dapr.AspNetCore.csproj", "{08D602F6-7C11-4653-B70B-B56333BF6FD2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{B2DB41EE-45F5-447B-95E8-38E1E8B70C4E}"
ProjectSection(SolutionItems) = preProject
samples\.editorconfig = samples\.editorconfig
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{DD020B34-460F-455F-8D17-CF4A949F100B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Client.Test", "test\Dapr.Client.Test\Dapr.Client.Test.csproj", "{383609C1-F43F-49EB-85E4-1964EE7F0F14}"
@ -33,51 +27,133 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1BD1276E-D28A-45EA-89B1-6AD48471500D}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
README.md = README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Actors.AspNetCore.Test", "test\Dapr.Actors.AspNetCore.Test\Dapr.Actors.AspNetCore.Test.csproj", "{9C1D6ABA-5EDE-4FA0-A8A9-0AB98CB74737}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Actors.AspNetCore.Test", "test\Dapr.Actors.AspNetCore.Test\Dapr.Actors.AspNetCore.Test.csproj", "{9C1D6ABA-5EDE-4FA0-A8A9-0AB98CB74737}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Actors.AspNetCore.IntegrationTest", "test\Dapr.Actors.AspNetCore.IntegrationTest\Dapr.Actors.AspNetCore.IntegrationTest.csproj", "{95BAF30B-8089-42CE-8530-6DFBCE1F6A07}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Actors.AspNetCore.IntegrationTest", "test\Dapr.Actors.AspNetCore.IntegrationTest\Dapr.Actors.AspNetCore.IntegrationTest.csproj", "{95BAF30B-8089-42CE-8530-6DFBCE1F6A07}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Actors.AspNetCore.IntegrationTest.App", "test\Dapr.Actors.AspNetCore.IntegrationTest.App\Dapr.Actors.AspNetCore.IntegrationTest.App.csproj", "{1BA7E772-8AA7-4D5A-800D-66B17F62421C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Actors.AspNetCore.IntegrationTest.App", "test\Dapr.Actors.AspNetCore.IntegrationTest.App\Dapr.Actors.AspNetCore.IntegrationTest.App.csproj", "{1BA7E772-8AA7-4D5A-800D-66B17F62421C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Extensions.Configuration.Test", "test\Dapr.Extensions.Configuration.Test\Dapr.Extensions.Configuration.Test.csproj", "{78FC19B2-396C-4ED2-BFD9-6C5667C61666}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Extensions.Configuration.Test", "test\Dapr.Extensions.Configuration.Test\Dapr.Extensions.Configuration.Test.csproj", "{78FC19B2-396C-4ED2-BFD9-6C5667C61666}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Extensions.Configuration", "src\Dapr.Extensions.Configuration\Dapr.Extensions.Configuration.csproj", "{B615B353-476C-43B9-A776-B193B0DBD256}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Extensions.Configuration", "src\Dapr.Extensions.Configuration\Dapr.Extensions.Configuration.csproj", "{B615B353-476C-43B9-A776-B193B0DBD256}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{D687DDC4-66C5-4667-9E3A-FD8B78ECAA78}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AspNetCore", "AspNetCore", "{A11DC259-D1DB-4686-AD28-A427D0BABA83}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrpcServiceSample", "examples\AspNetCore\GrpcServiceSample\GrpcServiceSample.csproj", "{2EC50C79-782D-4985-ABB1-AD07F35D1621}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GrpcServiceSample", "examples\AspNetCore\GrpcServiceSample\GrpcServiceSample.csproj", "{2EC50C79-782D-4985-ABB1-AD07F35D1621}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RoutingSample", "examples\AspNetCore\RoutingSample\RoutingSample.csproj", "{15A16323-2CCA-472E-BE79-07259DAD5F6F}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RoutingSample", "examples\AspNetCore\RoutingSample\RoutingSample.csproj", "{15A16323-2CCA-472E-BE79-07259DAD5F6F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SecretStoreConfigurationProviderSample", "examples\AspNetCore\SecretStoreConfigurationProviderSample\SecretStoreConfigurationProviderSample.csproj", "{5BACBA51-03FE-4CE1-B0F5-9E9C2A132FAB}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SecretStoreConfigurationProviderSample", "examples\AspNetCore\SecretStoreConfigurationProviderSample\SecretStoreConfigurationProviderSample.csproj", "{5BACBA51-03FE-4CE1-B0F5-9E9C2A132FAB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControllerSample", "examples\AspNetCore\ControllerSample\ControllerSample.csproj", "{3160CC92-1D6E-42CB-AE89-9401C8CEC5CB}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ControllerSample", "examples\AspNetCore\ControllerSample\ControllerSample.csproj", "{3160CC92-1D6E-42CB-AE89-9401C8CEC5CB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Actor", "Actor", "{02374BD0-BF0B-40F8-A04A-C4C4D61D4992}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IDemoActor", "examples\Actor\IDemoActor\IDemoActor.csproj", "{7957E852-1291-4FAA-9034-FB66CE817FF1}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IDemoActor", "examples\Actor\IDemoActor\IDemoActor.csproj", "{7957E852-1291-4FAA-9034-FB66CE817FF1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DemoActor", "examples\Actor\DemoActor\DemoActor.csproj", "{626D74DD-4F37-4F74-87A3-5A6888684F5E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DemoActor", "examples\Actor\DemoActor\DemoActor.csproj", "{626D74DD-4F37-4F74-87A3-5A6888684F5E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ActorClient", "examples\Actor\ActorClient\ActorClient.csproj", "{CC0A5C98-ACDE-4139-BA2F-2995A9B8E18C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ActorClient", "examples\Actor\ActorClient\ActorClient.csproj", "{CC0A5C98-ACDE-4139-BA2F-2995A9B8E18C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Client", "Client", "{A7F41094-8648-446B-AECD-DCC2CC871F73}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StateManagement", "examples\Client\StateManagement\StateManagement.csproj", "{F70AC78E-8925-4770-832A-2FC67A620EB2}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StateManagement", "examples\Client\StateManagement\StateManagement.csproj", "{F70AC78E-8925-4770-832A-2FC67A620EB2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceInvocation", "examples\Client\ServiceInvocation\ServiceInvocation.csproj", "{8B570E70-0E73-4042-A4B6-1CC3CC782A65}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceInvocation", "examples\Client\ServiceInvocation\ServiceInvocation.csproj", "{8B570E70-0E73-4042-A4B6-1CC3CC782A65}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PublishSubscribe", "examples\Client\PublishSubscribe\PublishSubscribe.csproj", "{DE6913E3-E5D9-4D1D-95F9-9FED87BD09BC}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.E2E.Test", "test\Dapr.E2E.Test\Dapr.E2E.Test.csproj", "{4AA9E7B7-36BF-4AAE-BFA3-C9CE8740F4A0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.E2E.Test", "test\Dapr.E2E.Test\Dapr.E2E.Test.csproj", "{4AA9E7B7-36BF-4AAE-BFA3-C9CE8740F4A0}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.E2E.Test.App", "test\Dapr.E2E.Test.App\Dapr.E2E.Test.App.csproj", "{345FC3FB-D1E9-4AE8-9052-17D20AB01FA2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.E2E.Test.App", "test\Dapr.E2E.Test.App\Dapr.E2E.Test.App.csproj", "{345FC3FB-D1E9-4AE8-9052-17D20AB01FA2}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.E2E.Test.Actors", "test\Dapr.E2E.Test.Actors\Dapr.E2E.Test.Actors.csproj", "{2AED1542-A8ED-488D-B6D0-E16AB5D6EF6C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.E2E.Test.Actors", "test\Dapr.E2E.Test.Actors\Dapr.E2E.Test.Actors.csproj", "{2AED1542-A8ED-488D-B6D0-E16AB5D6EF6C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.E2E.Test.App.Grpc", "test\Dapr.E2E.Test.App.Grpc\Dapr.E2E.Test.App.Grpc.csproj", "{E8212911-344B-4638-ADC3-B215BCDCAFD1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfigurationApi", "examples\Client\ConfigurationApi\ConfigurationApi.csproj", "{F80F837E-D2FC-4FFC-B68F-3CF0EC015F66}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.E2E.Test.App.ReentrantActors", "test\Dapr.E2E.Test.App.ReentrantActor\Dapr.E2E.Test.App.ReentrantActors.csproj", "{5BE7F505-7D77-4C3A-ABFD-54088774DAA7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DistributedLock", "examples\Client\DistributedLock\DistributedLock.csproj", "{35031EDB-C0DE-453A-8335-D2EBEA2FC640}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Workflow", "src\Dapr.Workflow\Dapr.Workflow.csproj", "{07578B6C-9B96-4B3D-BA2E-7800EFCA7F99}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Workflow", "Workflow", "{BF3ED6BF-ADF3-4D25-8E89-02FB8D945CA9}"
ProjectSection(SolutionItems) = preProject
examples\Workflow\README.md = examples\Workflow\README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WorkflowConsoleApp", "examples\Workflow\WorkflowConsoleApp\WorkflowConsoleApp.csproj", "{5C61ABED-7623-4C28-A5C9-C5972A0F669C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PublishSubscribe", "PublishSubscribe", "{0EF6EA64-D7C3-420D-9890-EAE8D54A57E6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PublishEventExample", "examples\Client\PublishSubscribe\PublishEventExample\PublishEventExample.csproj", "{4A175C27-EAFE-47E7-90F6-873B37863656}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BulkPublishEventExample", "examples\Client\PublishSubscribe\BulkPublishEventExample\BulkPublishEventExample.csproj", "{DDC41278-FB60-403A-B969-2AEBD7C2D83C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WorkflowUnitTest", "examples\Workflow\WorkflowUnitTest\WorkflowUnitTest.csproj", "{8CA09061-2BEF-4506-A763-07062D2BD6AC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GeneratedActor", "GeneratedActor", "{7592AFA4-426B-42F3-AE82-957C86814482}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ActorClient", "examples\GeneratedActor\ActorClient\ActorClient.csproj", "{61C24126-F39D-4BEA-96DC-FC87BA730554}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ActorCommon", "examples\GeneratedActor\ActorCommon\ActorCommon.csproj", "{CB903D21-4869-42EF-BDD6-5B1CFF674337}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Actors.Generators", "src\Dapr.Actors.Generators\Dapr.Actors.Generators.csproj", "{980B5FD8-0107-41F7-8FAD-E4E8BAE8A625}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ActorService", "examples\GeneratedActor\ActorService\ActorService.csproj", "{7C06FE2D-6C62-48F5-A505-F0D715C554DE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Actors.Generators.Test", "test\Dapr.Actors.Generators.Test\Dapr.Actors.Generators.Test.csproj", "{AF89083D-4715-42E6-93E9-38497D12A8A6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.E2E.Test.Actors.Generators", "test\Dapr.E2E.Test.Actors.Generators\Dapr.E2E.Test.Actors.Generators.csproj", "{B5CDB0DC-B26D-48F1-B934-FE5C1C991940}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cryptography", "examples\Client\Cryptography\Cryptography.csproj", "{C74FBA78-13E8-407F-A173-4555AEE41FF3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Protos", "src\Dapr.Protos\Dapr.Protos.csproj", "{DFBABB04-50E9-42F6-B470-310E1B545638}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Common", "src\Dapr.Common\Dapr.Common.csproj", "{B445B19C-A925-4873-8CB7-8317898B6970}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Common.Test", "test\Dapr.Common.Test\Dapr.Common.Test.csproj", "{CDB47863-BEBD-4841-A807-46D868962521}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.AI", "src\Dapr.AI\Dapr.AI.csproj", "{273F2527-1658-4CCF-8DC6-600E921188C5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.AI.Test", "test\Dapr.AI.Test\Dapr.AI.Test.csproj", "{2F3700EF-1CDA-4C15-AC88-360230000ECD}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AI", "AI", "{3046DBF4-C2FF-4F3A-9176-E1C01E0A90E5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConversationalAI", "examples\AI\ConversationalAI\ConversationalAI.csproj", "{11011FF8-77EA-4B25-96C0-29D4D486EF1C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkflowExternalInteraction", "examples\Workflow\WorkflowExternalInteraction\WorkflowExternalInteraction.csproj", "{43CB06A9-7E88-4C5F-BFB8-947E072CBC9F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkflowMonitor", "examples\Workflow\WorkflowMonitor\WorkflowMonitor.csproj", "{7F73A3D8-FFC2-4E31-AA3D-A4840316A8C6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkflowTaskChaining", "examples\Workflow\WorkflowTaskChaining\WorkflowTaskChaining.csproj", "{945DD3B7-94E5-435E-B3CB-796C20A652C7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkflowSubworkflow", "examples\Workflow\WorkflowSubworkflow\WorkflowSubworkflow.csproj", "{FD3E9371-3134-4235-8E80-32226DFB4B1F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkflowFanOutFanIn", "examples\Workflow\WorkflowFanOutFanIn\WorkflowFanOutFanIn.csproj", "{D83B27F3-4401-42F5-843E-147566B4999A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkflowAsyncOperations", "examples\Workflow\WorkflowAsyncOperations\WorkflowAsyncOperations.csproj", "{00359961-0C50-4BB1-A794-8B06DE991639}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Messaging.Test", "test\Dapr.Messaging.Test\Dapr.Messaging.Test.csproj", "{4E04EB35-7FD2-4FDB-B09A-F75CE24053B9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Messaging", "src\Dapr.Messaging\Dapr.Messaging.csproj", "{0EAE36A1-B578-4F13-A113-7A477ECA1BDA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StreamingSubscriptionExample", "examples\Client\PublishSubscribe\StreamingSubscriptionExample\StreamingSubscriptionExample.csproj", "{290D1278-F613-4DF3-9DF5-F37E38CDC363}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Jobs", "src\Dapr.Jobs\Dapr.Jobs.csproj", "{C8BB6A85-A7EA-40C0-893D-F36F317829B3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Jobs.Test", "test\Dapr.Jobs.Test\Dapr.Jobs.Test.csproj", "{BF9828E9-5597-4D42-AA6E-6E6C12214204}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Jobs", "Jobs", "{D9697361-232F-465D-A136-4561E0E88488}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JobsSample", "examples\Jobs\JobsSample\JobsSample.csproj", "{9CAF360E-5AD3-4C4F-89A0-327EEB70D673}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.Workflow.Test", "test\Dapr.Workflow.Test\Dapr.Workflow.Test.csproj", "{E90114C6-86FC-43B8-AE5C-D9273CF21FE4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -177,10 +253,6 @@ Global
{8B570E70-0E73-4042-A4B6-1CC3CC782A65}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8B570E70-0E73-4042-A4B6-1CC3CC782A65}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8B570E70-0E73-4042-A4B6-1CC3CC782A65}.Release|Any CPU.Build.0 = Release|Any CPU
{DE6913E3-E5D9-4D1D-95F9-9FED87BD09BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DE6913E3-E5D9-4D1D-95F9-9FED87BD09BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DE6913E3-E5D9-4D1D-95F9-9FED87BD09BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DE6913E3-E5D9-4D1D-95F9-9FED87BD09BC}.Release|Any CPU.Build.0 = Release|Any CPU
{4AA9E7B7-36BF-4AAE-BFA3-C9CE8740F4A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4AA9E7B7-36BF-4AAE-BFA3-C9CE8740F4A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4AA9E7B7-36BF-4AAE-BFA3-C9CE8740F4A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -193,6 +265,144 @@ Global
{2AED1542-A8ED-488D-B6D0-E16AB5D6EF6C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2AED1542-A8ED-488D-B6D0-E16AB5D6EF6C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2AED1542-A8ED-488D-B6D0-E16AB5D6EF6C}.Release|Any CPU.Build.0 = Release|Any CPU
{E8212911-344B-4638-ADC3-B215BCDCAFD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E8212911-344B-4638-ADC3-B215BCDCAFD1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E8212911-344B-4638-ADC3-B215BCDCAFD1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E8212911-344B-4638-ADC3-B215BCDCAFD1}.Release|Any CPU.Build.0 = Release|Any CPU
{F80F837E-D2FC-4FFC-B68F-3CF0EC015F66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F80F837E-D2FC-4FFC-B68F-3CF0EC015F66}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F80F837E-D2FC-4FFC-B68F-3CF0EC015F66}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F80F837E-D2FC-4FFC-B68F-3CF0EC015F66}.Release|Any CPU.Build.0 = Release|Any CPU
{5BE7F505-7D77-4C3A-ABFD-54088774DAA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5BE7F505-7D77-4C3A-ABFD-54088774DAA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5BE7F505-7D77-4C3A-ABFD-54088774DAA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5BE7F505-7D77-4C3A-ABFD-54088774DAA7}.Release|Any CPU.Build.0 = Release|Any CPU
{35031EDB-C0DE-453A-8335-D2EBEA2FC640}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{35031EDB-C0DE-453A-8335-D2EBEA2FC640}.Debug|Any CPU.Build.0 = Debug|Any CPU
{35031EDB-C0DE-453A-8335-D2EBEA2FC640}.Release|Any CPU.ActiveCfg = Release|Any CPU
{35031EDB-C0DE-453A-8335-D2EBEA2FC640}.Release|Any CPU.Build.0 = Release|Any CPU
{07578B6C-9B96-4B3D-BA2E-7800EFCA7F99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{07578B6C-9B96-4B3D-BA2E-7800EFCA7F99}.Debug|Any CPU.Build.0 = Debug|Any CPU
{07578B6C-9B96-4B3D-BA2E-7800EFCA7F99}.Release|Any CPU.ActiveCfg = Release|Any CPU
{07578B6C-9B96-4B3D-BA2E-7800EFCA7F99}.Release|Any CPU.Build.0 = Release|Any CPU
{5C61ABED-7623-4C28-A5C9-C5972A0F669C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5C61ABED-7623-4C28-A5C9-C5972A0F669C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5C61ABED-7623-4C28-A5C9-C5972A0F669C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5C61ABED-7623-4C28-A5C9-C5972A0F669C}.Release|Any CPU.Build.0 = Release|Any CPU
{4A175C27-EAFE-47E7-90F6-873B37863656}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A175C27-EAFE-47E7-90F6-873B37863656}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A175C27-EAFE-47E7-90F6-873B37863656}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A175C27-EAFE-47E7-90F6-873B37863656}.Release|Any CPU.Build.0 = Release|Any CPU
{DDC41278-FB60-403A-B969-2AEBD7C2D83C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DDC41278-FB60-403A-B969-2AEBD7C2D83C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DDC41278-FB60-403A-B969-2AEBD7C2D83C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DDC41278-FB60-403A-B969-2AEBD7C2D83C}.Release|Any CPU.Build.0 = Release|Any CPU
{8CA09061-2BEF-4506-A763-07062D2BD6AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8CA09061-2BEF-4506-A763-07062D2BD6AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61C24126-F39D-4BEA-96DC-FC87BA730554}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{61C24126-F39D-4BEA-96DC-FC87BA730554}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61C24126-F39D-4BEA-96DC-FC87BA730554}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61C24126-F39D-4BEA-96DC-FC87BA730554}.Release|Any CPU.Build.0 = Release|Any CPU
{CB903D21-4869-42EF-BDD6-5B1CFF674337}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CB903D21-4869-42EF-BDD6-5B1CFF674337}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CB903D21-4869-42EF-BDD6-5B1CFF674337}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CB903D21-4869-42EF-BDD6-5B1CFF674337}.Release|Any CPU.Build.0 = Release|Any CPU
{980B5FD8-0107-41F7-8FAD-E4E8BAE8A625}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{980B5FD8-0107-41F7-8FAD-E4E8BAE8A625}.Debug|Any CPU.Build.0 = Debug|Any CPU
{980B5FD8-0107-41F7-8FAD-E4E8BAE8A625}.Release|Any CPU.ActiveCfg = Release|Any CPU
{980B5FD8-0107-41F7-8FAD-E4E8BAE8A625}.Release|Any CPU.Build.0 = Release|Any CPU
{7C06FE2D-6C62-48F5-A505-F0D715C554DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7C06FE2D-6C62-48F5-A505-F0D715C554DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7C06FE2D-6C62-48F5-A505-F0D715C554DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7C06FE2D-6C62-48F5-A505-F0D715C554DE}.Release|Any CPU.Build.0 = Release|Any CPU
{AF89083D-4715-42E6-93E9-38497D12A8A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AF89083D-4715-42E6-93E9-38497D12A8A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AF89083D-4715-42E6-93E9-38497D12A8A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AF89083D-4715-42E6-93E9-38497D12A8A6}.Release|Any CPU.Build.0 = Release|Any CPU
{B5CDB0DC-B26D-48F1-B934-FE5C1C991940}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B5CDB0DC-B26D-48F1-B934-FE5C1C991940}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B5CDB0DC-B26D-48F1-B934-FE5C1C991940}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B5CDB0DC-B26D-48F1-B934-FE5C1C991940}.Release|Any CPU.Build.0 = Release|Any CPU
{C74FBA78-13E8-407F-A173-4555AEE41FF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C74FBA78-13E8-407F-A173-4555AEE41FF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C74FBA78-13E8-407F-A173-4555AEE41FF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C74FBA78-13E8-407F-A173-4555AEE41FF3}.Release|Any CPU.Build.0 = Release|Any CPU
{DFBABB04-50E9-42F6-B470-310E1B545638}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DFBABB04-50E9-42F6-B470-310E1B545638}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DFBABB04-50E9-42F6-B470-310E1B545638}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DFBABB04-50E9-42F6-B470-310E1B545638}.Release|Any CPU.Build.0 = Release|Any CPU
{B445B19C-A925-4873-8CB7-8317898B6970}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B445B19C-A925-4873-8CB7-8317898B6970}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B445B19C-A925-4873-8CB7-8317898B6970}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B445B19C-A925-4873-8CB7-8317898B6970}.Release|Any CPU.Build.0 = Release|Any CPU
{CDB47863-BEBD-4841-A807-46D868962521}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CDB47863-BEBD-4841-A807-46D868962521}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CDB47863-BEBD-4841-A807-46D868962521}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CDB47863-BEBD-4841-A807-46D868962521}.Release|Any CPU.Build.0 = Release|Any CPU
{273F2527-1658-4CCF-8DC6-600E921188C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{273F2527-1658-4CCF-8DC6-600E921188C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{273F2527-1658-4CCF-8DC6-600E921188C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{273F2527-1658-4CCF-8DC6-600E921188C5}.Release|Any CPU.Build.0 = Release|Any CPU
{2F3700EF-1CDA-4C15-AC88-360230000ECD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2F3700EF-1CDA-4C15-AC88-360230000ECD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F3700EF-1CDA-4C15-AC88-360230000ECD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F3700EF-1CDA-4C15-AC88-360230000ECD}.Release|Any CPU.Build.0 = Release|Any CPU
{11011FF8-77EA-4B25-96C0-29D4D486EF1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{11011FF8-77EA-4B25-96C0-29D4D486EF1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{11011FF8-77EA-4B25-96C0-29D4D486EF1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{11011FF8-77EA-4B25-96C0-29D4D486EF1C}.Release|Any CPU.Build.0 = Release|Any CPU
{43CB06A9-7E88-4C5F-BFB8-947E072CBC9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{43CB06A9-7E88-4C5F-BFB8-947E072CBC9F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{43CB06A9-7E88-4C5F-BFB8-947E072CBC9F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{43CB06A9-7E88-4C5F-BFB8-947E072CBC9F}.Release|Any CPU.Build.0 = Release|Any CPU
{7F73A3D8-FFC2-4E31-AA3D-A4840316A8C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7F73A3D8-FFC2-4E31-AA3D-A4840316A8C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7F73A3D8-FFC2-4E31-AA3D-A4840316A8C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7F73A3D8-FFC2-4E31-AA3D-A4840316A8C6}.Release|Any CPU.Build.0 = Release|Any CPU
{945DD3B7-94E5-435E-B3CB-796C20A652C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{945DD3B7-94E5-435E-B3CB-796C20A652C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{945DD3B7-94E5-435E-B3CB-796C20A652C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{945DD3B7-94E5-435E-B3CB-796C20A652C7}.Release|Any CPU.Build.0 = Release|Any CPU
{FD3E9371-3134-4235-8E80-32226DFB4B1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FD3E9371-3134-4235-8E80-32226DFB4B1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FD3E9371-3134-4235-8E80-32226DFB4B1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FD3E9371-3134-4235-8E80-32226DFB4B1F}.Release|Any CPU.Build.0 = Release|Any CPU
{D83B27F3-4401-42F5-843E-147566B4999A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D83B27F3-4401-42F5-843E-147566B4999A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D83B27F3-4401-42F5-843E-147566B4999A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D83B27F3-4401-42F5-843E-147566B4999A}.Release|Any CPU.Build.0 = Release|Any CPU
{00359961-0C50-4BB1-A794-8B06DE991639}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{00359961-0C50-4BB1-A794-8B06DE991639}.Debug|Any CPU.Build.0 = Debug|Any CPU
{00359961-0C50-4BB1-A794-8B06DE991639}.Release|Any CPU.ActiveCfg = Release|Any CPU
{00359961-0C50-4BB1-A794-8B06DE991639}.Release|Any CPU.Build.0 = Release|Any CPU
{4E04EB35-7FD2-4FDB-B09A-F75CE24053B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E04EB35-7FD2-4FDB-B09A-F75CE24053B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E04EB35-7FD2-4FDB-B09A-F75CE24053B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E04EB35-7FD2-4FDB-B09A-F75CE24053B9}.Release|Any CPU.Build.0 = Release|Any CPU
{0EAE36A1-B578-4F13-A113-7A477ECA1BDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0EAE36A1-B578-4F13-A113-7A477ECA1BDA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0EAE36A1-B578-4F13-A113-7A477ECA1BDA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0EAE36A1-B578-4F13-A113-7A477ECA1BDA}.Release|Any CPU.Build.0 = Release|Any CPU
{290D1278-F613-4DF3-9DF5-F37E38CDC363}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{290D1278-F613-4DF3-9DF5-F37E38CDC363}.Debug|Any CPU.Build.0 = Debug|Any CPU
{290D1278-F613-4DF3-9DF5-F37E38CDC363}.Release|Any CPU.ActiveCfg = Release|Any CPU
{290D1278-F613-4DF3-9DF5-F37E38CDC363}.Release|Any CPU.Build.0 = Release|Any CPU
{C8BB6A85-A7EA-40C0-893D-F36F317829B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C8BB6A85-A7EA-40C0-893D-F36F317829B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C8BB6A85-A7EA-40C0-893D-F36F317829B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C8BB6A85-A7EA-40C0-893D-F36F317829B3}.Release|Any CPU.Build.0 = Release|Any CPU
{BF9828E9-5597-4D42-AA6E-6E6C12214204}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BF9828E9-5597-4D42-AA6E-6E6C12214204}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF9828E9-5597-4D42-AA6E-6E6C12214204}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BF9828E9-5597-4D42-AA6E-6E6C12214204}.Release|Any CPU.Build.0 = Release|Any CPU
{9CAF360E-5AD3-4C4F-89A0-327EEB70D673}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9CAF360E-5AD3-4C4F-89A0-327EEB70D673}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9CAF360E-5AD3-4C4F-89A0-327EEB70D673}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9CAF360E-5AD3-4C4F-89A0-327EEB70D673}.Release|Any CPU.Build.0 = Release|Any CPU
{E90114C6-86FC-43B8-AE5C-D9273CF21FE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E90114C6-86FC-43B8-AE5C-D9273CF21FE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E90114C6-86FC-43B8-AE5C-D9273CF21FE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E90114C6-86FC-43B8-AE5C-D9273CF21FE4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -224,10 +434,49 @@ Global
{A7F41094-8648-446B-AECD-DCC2CC871F73} = {D687DDC4-66C5-4667-9E3A-FD8B78ECAA78}
{F70AC78E-8925-4770-832A-2FC67A620EB2} = {A7F41094-8648-446B-AECD-DCC2CC871F73}
{8B570E70-0E73-4042-A4B6-1CC3CC782A65} = {A7F41094-8648-446B-AECD-DCC2CC871F73}
{DE6913E3-E5D9-4D1D-95F9-9FED87BD09BC} = {A7F41094-8648-446B-AECD-DCC2CC871F73}
{4AA9E7B7-36BF-4AAE-BFA3-C9CE8740F4A0} = {DD020B34-460F-455F-8D17-CF4A949F100B}
{345FC3FB-D1E9-4AE8-9052-17D20AB01FA2} = {DD020B34-460F-455F-8D17-CF4A949F100B}
{2AED1542-A8ED-488D-B6D0-E16AB5D6EF6C} = {DD020B34-460F-455F-8D17-CF4A949F100B}
{E8212911-344B-4638-ADC3-B215BCDCAFD1} = {DD020B34-460F-455F-8D17-CF4A949F100B}
{F80F837E-D2FC-4FFC-B68F-3CF0EC015F66} = {A7F41094-8648-446B-AECD-DCC2CC871F73}
{5BE7F505-7D77-4C3A-ABFD-54088774DAA7} = {DD020B34-460F-455F-8D17-CF4A949F100B}
{35031EDB-C0DE-453A-8335-D2EBEA2FC640} = {A7F41094-8648-446B-AECD-DCC2CC871F73}
{07578B6C-9B96-4B3D-BA2E-7800EFCA7F99} = {27C5D71D-0721-4221-9286-B94AB07B58CF}
{BF3ED6BF-ADF3-4D25-8E89-02FB8D945CA9} = {D687DDC4-66C5-4667-9E3A-FD8B78ECAA78}
{5C61ABED-7623-4C28-A5C9-C5972A0F669C} = {BF3ED6BF-ADF3-4D25-8E89-02FB8D945CA9}
{0EF6EA64-D7C3-420D-9890-EAE8D54A57E6} = {A7F41094-8648-446B-AECD-DCC2CC871F73}
{4A175C27-EAFE-47E7-90F6-873B37863656} = {0EF6EA64-D7C3-420D-9890-EAE8D54A57E6}
{DDC41278-FB60-403A-B969-2AEBD7C2D83C} = {0EF6EA64-D7C3-420D-9890-EAE8D54A57E6}
{8CA09061-2BEF-4506-A763-07062D2BD6AC} = {BF3ED6BF-ADF3-4D25-8E89-02FB8D945CA9}
{7592AFA4-426B-42F3-AE82-957C86814482} = {D687DDC4-66C5-4667-9E3A-FD8B78ECAA78}
{61C24126-F39D-4BEA-96DC-FC87BA730554} = {7592AFA4-426B-42F3-AE82-957C86814482}
{CB903D21-4869-42EF-BDD6-5B1CFF674337} = {7592AFA4-426B-42F3-AE82-957C86814482}
{980B5FD8-0107-41F7-8FAD-E4E8BAE8A625} = {27C5D71D-0721-4221-9286-B94AB07B58CF}
{7C06FE2D-6C62-48F5-A505-F0D715C554DE} = {7592AFA4-426B-42F3-AE82-957C86814482}
{AF89083D-4715-42E6-93E9-38497D12A8A6} = {DD020B34-460F-455F-8D17-CF4A949F100B}
{B5CDB0DC-B26D-48F1-B934-FE5C1C991940} = {DD020B34-460F-455F-8D17-CF4A949F100B}
{C74FBA78-13E8-407F-A173-4555AEE41FF3} = {A7F41094-8648-446B-AECD-DCC2CC871F73}
{DFBABB04-50E9-42F6-B470-310E1B545638} = {27C5D71D-0721-4221-9286-B94AB07B58CF}
{B445B19C-A925-4873-8CB7-8317898B6970} = {27C5D71D-0721-4221-9286-B94AB07B58CF}
{CDB47863-BEBD-4841-A807-46D868962521} = {DD020B34-460F-455F-8D17-CF4A949F100B}
{273F2527-1658-4CCF-8DC6-600E921188C5} = {27C5D71D-0721-4221-9286-B94AB07B58CF}
{2F3700EF-1CDA-4C15-AC88-360230000ECD} = {DD020B34-460F-455F-8D17-CF4A949F100B}
{3046DBF4-C2FF-4F3A-9176-E1C01E0A90E5} = {D687DDC4-66C5-4667-9E3A-FD8B78ECAA78}
{11011FF8-77EA-4B25-96C0-29D4D486EF1C} = {3046DBF4-C2FF-4F3A-9176-E1C01E0A90E5}
{43CB06A9-7E88-4C5F-BFB8-947E072CBC9F} = {BF3ED6BF-ADF3-4D25-8E89-02FB8D945CA9}
{7F73A3D8-FFC2-4E31-AA3D-A4840316A8C6} = {BF3ED6BF-ADF3-4D25-8E89-02FB8D945CA9}
{945DD3B7-94E5-435E-B3CB-796C20A652C7} = {BF3ED6BF-ADF3-4D25-8E89-02FB8D945CA9}
{FD3E9371-3134-4235-8E80-32226DFB4B1F} = {BF3ED6BF-ADF3-4D25-8E89-02FB8D945CA9}
{D83B27F3-4401-42F5-843E-147566B4999A} = {BF3ED6BF-ADF3-4D25-8E89-02FB8D945CA9}
{00359961-0C50-4BB1-A794-8B06DE991639} = {BF3ED6BF-ADF3-4D25-8E89-02FB8D945CA9}
{4E04EB35-7FD2-4FDB-B09A-F75CE24053B9} = {DD020B34-460F-455F-8D17-CF4A949F100B}
{0EAE36A1-B578-4F13-A113-7A477ECA1BDA} = {27C5D71D-0721-4221-9286-B94AB07B58CF}
{290D1278-F613-4DF3-9DF5-F37E38CDC363} = {0EF6EA64-D7C3-420D-9890-EAE8D54A57E6}
{C8BB6A85-A7EA-40C0-893D-F36F317829B3} = {27C5D71D-0721-4221-9286-B94AB07B58CF}
{BF9828E9-5597-4D42-AA6E-6E6C12214204} = {DD020B34-460F-455F-8D17-CF4A949F100B}
{D9697361-232F-465D-A136-4561E0E88488} = {D687DDC4-66C5-4667-9E3A-FD8B78ECAA78}
{9CAF360E-5AD3-4C4F-89A0-327EEB70D673} = {D9697361-232F-465D-A136-4561E0E88488}
{E90114C6-86FC-43B8-AE5C-D9273CF21FE4} = {DD020B34-460F-455F-8D17-CF4A949F100B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {65220BF2-EAE1-4CB2-AA58-EBE80768CB40}

View File

@ -6,18 +6,112 @@ weight: 3000
description: Guidelines for contributing to the Dapr .NET SDK
---
When contributing to the [.NET SDK](https://github.com/dapr/dotnet-sdk) the following rules and best-practices should be followed.
# Welcome!
If you're reading this, you're likely interested in contributing to Dapr and/or the Dapr .NET SDK. Welcome to the project
and thank you for your interest in contributing!
Please review the documentation, familiarize yourself with what Dapr is and what it's seeking to accomplish and reach
out on [Discord](https://bit.ly/dapr-discord). Let us know how you'd like to contribute and we'd be happy to chime in
with ideas and suggestions.
There are many ways to contribute to Dapr:
- Submit bug reports for the [Dapr runtime](https://github.com/dapr/dapr/issues/new/choose) or the [Dapr .NET SDK](https://github.com/dapr/dotnet-sdk/issues/new/choose)
- Propose new [runtime capabilities](https://github.com/dapr/proposals/issues/new/choose) or [SDK functionality](https://github.com/dapr/dotnet-sdk/issues/new/choose)
- Improve the documentation in either the [larger Dapr project](https://github.com/dapr/docs) or the [Dapr .NET SDK specifically](https://github.com/dapr/dotnet-sdk/tree/master/daprdocs)
- Add new or improve existing [components](https://github.com/dapr/components-contrib/) that implement the various building blocks
- Augment the [.NET pluggable component SDK capabilities](https://github.com/dapr-sandbox/components-dotnet-sdk)
- Improve the Dapr .NET SDK code base and/or fix a bug (detailed below)
If you're new to the code base, please feel encouraged to ask in the #dotnet-sdk channel in Discord about how
to implement changes or generally ask questions. You are not required to seek permission to work on anything, but do
note that if an issue is assigned to someone, it's an indication that someone might have already started work on it.
Especially if it's been a while since the last activity on that issue, please feel free to reach out and see if it's
still something they're interested in pursuing or whether you can take over, and open a pull request with your
implementation.
If you'd like to assign yourself to an issue, respond to the conversation with "/assign" and the bot will assign you
to it.
We have labeled some issues as `good-first-issue` or `help wanted` indicating that these are likely to be small,
self-contained changes.
If you're not certain about your implementation, please create it as a draft pull request and solicit feedback
from the [.NET maintainers](https://github.com/orgs/dapr/teams/maintainers-dotnet-sdk) by tagging
`@dapr/maintainers-dotnet-sdk` and providing some context about what you need assistance with.
# Contribution Rules and Best Practices
When contributing to the [.NET SDK](https://github.com/dapr/dotnet-sdk) the following rules and best-practices should
be followed.
## Pull Requests
Pull requests that contain only formatting changes are generally discouraged. Pull requests should instead seek to
fix a bug, add new functionality, or improve on existing capabilities.
Do aim to minimize the contents of your pull request to span only a single issue. Broad PRs that touch on a lot of files
are not likely to be reviewed or accepted in a short timeframe. Accommodating many different issues in a single PR makes
it hard to determine whether your code fully addresses the underlying issue(s) or not and complicates the code review.
## Tests
All pull requests should include unit and/or integration tests that reflect the nature of what was added or changed
so it's clear that the functionality works as intended. Avoid using auto-generated tests that duplicate testing the
same functionality several times. Rather, seek to improve code coverage by validating each possible path of your
changes so future contributors can more easily navigate the contours of your logic and more readily identify limitations.
## Examples
The `examples` directory contains code samples for users to run to try out specific functionality of the various .NET SDK packages and extensions. When writing new and updated samples keep in mind:
The `examples` directory contains code samples for users to run to try out specific functionality of the various
Dapr .NET SDK packages and extensions. When writing new and updated samples keep in mind:
- All examples should be runnable on Windows, Linux, and MacOS. While .NET Core code is consistent among operating systems, any pre/post example commands should provide options through [codetabs]({{< ref "contributing-docs.md#tabbed-content" >}})
- Contain steps to download/install any required pre-requisites. Someone coming in with a fresh OS install should be able to start on the example and complete it without an error. Links to external download pages are fine.
- All examples should be runnable on Windows, Linux, and MacOS. While .NET Core code is consistent among operating
systems, any pre/post example commands should provide options through
[codetabs]({{< ref "contributing-docs.md#tabbed-content" >}})
- Contain steps to download/install any required pre-requisites. Someone coming in with a fresh OS install should be
able to start on the example and complete it without an error. Links to external download pages are fine.
## Docs
## Documentation
The `daprdocs` directory contains the markdown files that are rendered into the [Dapr Docs](https://docs.dapr.io) website. When the documentation website is built this repo is cloned and configured so that its contents are rendered with the docs content. When writing docs keep in mind:
The `daprdocs` directory contains the markdown files that are rendered into the [Dapr Docs](https://docs.dapr.io) website. When the
documentation website is built this repo is cloned and configured so that its contents are rendered with the docs
content. When writing docs keep in mind:
- All rules in the [docs guide]({{< ref contributing-docs.md >}}) should be followed in addition to these.
- All files and directories should be prefixed with `dotnet-` to ensure all file/directory names are globally unique across all Dapr documentation.
- All files and directories should be prefixed with `dotnet-` to ensure all file/directory names are globally
- unique across all Dapr documentation.
All pull requests should strive to include both XML documentation in the code clearly indicating what functionality
does and why it's there as well as changes to the published documentation to clarify for other developers how your change
improves the Dapr framework.
## GitHub Dapr Bot Commands
Checkout the [daprbot documentation](https://docs.dapr.io/contributing/daprbot/) for Github commands you can run in this repo for common tasks. For example,
you can comment `/assign` on an issue to assign it to yourself.
## Commit Sign-offs
All code submitted to the Dapr .NET SDK must be signed off by the developer authoring it. This means that every
commit must end with the following:
> Signed-off-by: First Last <flast@example.com>
The name and email address must match the registered GitHub name and email address of the user committing the changes.
We use a bot to detect this in pull requests and we will be unable to merge the PR if this check fails to validate.
If you notice that a PR has failed to validate because of a failed DCO check early on in the PR history, please consider
squashing the PR locally and resubmitting to ensure that the sign-off statement is included in the commit history.
# Languages, Tools and Processes
All source code in the Dapr .NET SDK is written in C# and targets the latest language version available to the earliest
supported .NET SDK. As of v1.15, this means that because .NET 6 is still supported, the latest language version available
is [C# version 10](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-version-history#c-version-10).
As of v1.15, the following versions of .NET are supported:
| Version | Notes |
| --- |-----------------------------------------------------------------|
| .NET 6 | Will be discontinued in v1.16 |
| .NET 7 | Only supported in Dapr.Workflows, will be discontinued in v1.16 |
| .NET 8 | Will continue to be supported in v1.16 |
| .NET 9 | Will continue to be supported in v1.16 |
Contributors are welcome to use whatever IDE they're most comfortable developing in, but please do not submit
IDE-specific preference files along with your contributions as these will be rejected.

View File

@ -5,10 +5,49 @@ linkTitle: ".NET"
weight: 1000
description: .NET SDK packages for developing Dapr applications
no_list: true
cascade:
github_repo: https://github.com/dapr/dotnet-sdk
github_subdir: daprdocs/content/en/dotnet-sdk-docs
path_base_for_github_subdir: content/en/developing-applications/sdks/dotnet/
github_branch: master
---
Dapr offers a variety of packages to help with the development of .NET applications. Using them you can create .NET clients, servers, and virtual actors with Dapr.
## Prerequisites
- [Dapr CLI]({{< ref install-dapr-cli.md >}}) installed
- Initialized [Dapr environment]({{< ref install-dapr-selfhost.md >}})
- [.NET 6](https://dotnet.microsoft.com/download), [.NET 8](https://dotnet.microsoft.com/download) or [.NET 9](https://dotnet.microsoft.com/download) installed
{{% alert title="Note" color="primary" %}}
Note that while .NET 6 is generally supported as the minimum .NET requirement across the Dapr .NET SDK packages
and .NET 7 is the minimally supported version of .NET by Dapr.Workflows in Dapr v1.15, only .NET 8 and .NET 9 will
continue to be supported by Dapr in v1.16 and later.
{{% /alert %}}
## Installation
To get started with the Client .NET SDK, install the Dapr .NET SDK package:
```sh
dotnet add package Dapr.Client
```
## Try it out
Put the Dapr .NET SDK to the test. Walk through the .NET quickstarts and tutorials to see Dapr in action:
| SDK samples | Description |
| ----------- | ----------- |
| [Quickstarts]({{< ref quickstarts >}}) | Experience Dapr's API building blocks in just a few minutes using the .NET SDK. |
| [SDK samples](https://github.com/dapr/dotnet-sdk/tree/master/examples) | Clone the SDK repo to try out some examples and get started. |
| [Pub/sub tutorial](https://github.com/dapr/quickstarts/tree/master/tutorials/pub-sub) | See how Dapr .NET SDK works alongside other Dapr SDKs to enable pub/sub applications. |
## Available packages
<div class="card-deck">
<div class="card">
<div class="card-body">
@ -21,7 +60,7 @@ Dapr offers a variety of packages to help with the development of .NET applicati
<div class="card-body">
<h5 class="card-title"><b>Server</b></h5>
<p class="card-text">Write servers and services in .NET using the Dapr SDK. Includes support for ASP.NET.</p>
<a href="{{< ref dotnet-server >}}" class="stretched-link"></a>
<a href="https://github.com/dapr/dotnet-sdk/tree/master/examples/AspNetCore" class="stretched-link"></a>
</div>
</div>
<div class="card">
@ -31,8 +70,33 @@ Dapr offers a variety of packages to help with the development of .NET applicati
<a href="{{< ref dotnet-actors >}}" class="stretched-link"></a>
</div>
</div>
<div class="card">
<div class="card-body">
<h5 class="card-title"><b>Workflow</b></h5>
<p class="card-text">Create and manage workflows that work with other Dapr APIs in .NET.</p>
<a href="{{< ref dotnet-workflow >}}" class="stretched-link"></a>
</div>
</div>
<div class="card">
<div class="card-body">
<h5 class="card-title"><b>Jobs</b></h5>
<p class="card-text">Create and manage the scheduling and orchestration of jobs in .NET.</p>
<a href="{{< ref dotnet-jobs >}}" class="stretched-link"></a>
</div>
</div>
<div class="card">
<div class="card-body">
<h5 class="card-title"><b>AI</b></h5>
<p class="card-text">Create and manage AI operations in .NET</p>
<a href="{{< ref dotnet-ai >}}" class="stretched-link"></a>
</div>
</div>
</div>
<br />
## More information
Learn more about local development options, or browse NuGet packages to add to your existing .NET applications.
<div class="card-deck">
<div class="card">
<div class="card-body">
@ -41,21 +105,6 @@ Dapr offers a variety of packages to help with the development of .NET applicati
<a href="{{< ref dotnet-development >}}" class="stretched-link"></a>
</div>
</div>
<div class="card">
<div class="card-body">
<h5 class="card-title"><b>Examples</b></h5>
<p class="card-text">Clone the .NET SDK repo to try out some of the examples and get started quickly.</p>
<a href="https://github.com/dapr/dotnet-sdk/tree/master/examples" class="stretched-link"></a>
</div>
</div>
<div class="card">
<div class="card-body">
<h5 class="card-title"><b>Troubleshooting</b></h5>
<p class="card-text">Detailed documentation on the Dapr API, CLI, bindings and more.</p>
<a href="{{< ref reference >}}" class="stretched-link"></a>
</div>
</div>
<div class="card">
<div class="card-body">
<h5 class="card-title"><b>NuGet packages</b></h5>
@ -64,4 +113,4 @@ Dapr offers a variety of packages to help with the development of .NET applicati
</div>
</div>
</div>
<br />
<br />

View File

@ -1,11 +1,11 @@
---
type: docs
title: "Getting started with the Dapr actors .NET SDK"
title: "Dapr actors .NET SDK"
linkTitle: "Actors"
weight: 40000
description: How to get up and running with the Dapr .NET SDK
weight: 30000
description: Get up and running with the Dapr actors .NET SDK
---
The Dapr actor package allows you to interact with Dapr virtual actors from a .NET application.
With the Dapr actor package, you can interact with Dapr virtual actors from a .NET application.
See [How to use Dapr actors]({{< ref dotnet-actors-howto.md >}}) for getting started instructions.
To get started, walk through the [Dapr actors]({{< ref dotnet-actors-howto.md >}}) how-to guide.

View File

@ -1,19 +1,17 @@
---
type: docs
title: "Dapr actor .NET usage guide"
title: "The IActorProxyFactory interface"
linkTitle: "Actors client"
weight: 100000
description: Learn all about using the actor client with the .NET SDK
description: Learn how to create actor clients with the IActorProxyFactory interface
---
## Using the IActorProxyFactory
Inside of an `Actor` class or an ASP.NET Core project, the `IActorProxyFactory` interface is recommended to create actor clients.
Inside of an `Actor` class or otherwise inside of an ASP.NET Core project you should use the `IActorProxyFactory` interface to create actor clients.
The `AddActors(...)` method will register actor services with ASP.NET Core dependency injection.
The `AddActors(...)` method will register actor services with ASP.NET Core dependency injection.
- Outside of an actor instance, the `IActorProxyFactory` instance is available through dependency injection as a singleton service.
- Inside an actor instance, the `IActorProxyFactory` instance is available as a property (`this.ProxyFactory`).
- **Outside of an actor instance:** The `IActorProxyFactory` instance is available through dependency injection as a singleton service.
- **Inside an actor instance:** The `IActorProxyFactory` instance is available as a property (`this.ProxyFactory`).
The following is an example of creating a proxy inside an actor:
@ -27,30 +25,35 @@ public Task<MyData> GetDataAsync()
}
```
> 💡 For a non-dependency-injected application you can use the static methods on `ActorProxy`. These methods are error prone when you need to configure custom settings, and should be avoided when possible.
In this guide, you will learn how to use `IActorProxyFactory`.
The guidance in this document will focus on `IActorProxyFactory`. `ActorProxy`'s static method functionality is identical except for the ability to manage configuration centrally.
{{% alert title="Tip" color="primary" %}}
For a non-dependency-injected application, you can use the static methods on `ActorProxy`. Since the `ActorProxy` methods are error prone, try to avoid using them when configuring custom settings.
{{% /alert %}}
## Identifying an actor
In order to communicate with an actor, you will need to know its type and id, and for a strongly-typed client one of its interfaces. All of the APIs on `IActorProxyFactory` will require an actor type and actor id.
All of the APIs on `IActorProxyFactory` will require an actor _type_ and actor _id_ to communicate with an actor. For strongly-typed clients, you also need one of its interfaces.
- The actor type uniquely identifies the actor implementation across the whole application.
- The actor id uniquely identifies an instance of that type.
- **Actor type** uniquely identifies the actor implementation across the whole application.
- **Actor id** uniquely identifies an instance of that type.
If you do not have an actor id and want to communicate with a new instance, you can use `ActorId.CreateRandom()` to create a randomized id. Since the random id is a cryptographically strong identifier, the runtime will create a new actor instance when you interact with it.
If you don't have an actor `id` and want to communicate with a new instance, create a random id with `ActorId.CreateRandom()`. Since the random id is a cryptographically strong identifier, the runtime will create a new actor instance when you interact with it.
You can use the type `ActorReference` to exchange an actor type and actor id with other actors as part of messages.
You can use the type `ActorReference` to exchange an actor type and actor id with other actors as part of messages.
## Two styles of actor client
The actor client supports two different styles of invocation: *strongly-typed* clients that use .NET interfaces and *weakly-typed* clients that use the `ActorProxy` class.
The actor client supports two different styles of invocation:
Since *strongly-typed* clients are based on .NET interfaces provide the typical benefits of strong-typing, however they do not work with non-.NET actors. You should use the *weakly-typed* client only when required for interop or other advanced reasons.
| Actor client style | Description |
| ------------------ | ----------- |
| Strongly-typed | Strongly-typed clients are based on .NET interfaces and provide the typical benefits of strong-typing. They don't work with non-.NET actors. |
| Weakly-typed | Weakly-typed clients use the `ActorProxy` class. It is recommended to use these only when required for interop or other advanced reasons. |
### Using a strongly-typed client
Use the `CreateActorProxy<>` method to create a strongly-typed client like the following example. `CreateActorProxy<>` requires an actor interface type, and will return an instance of that interface.
The following example uses the `CreateActorProxy<>` method to create a strongly-typed client. `CreateActorProxy<>` requires an actor interface type, and will return an instance of that interface.
```csharp
// Create a proxy for IOtherActor to type OtherActor with a random id
@ -64,7 +67,7 @@ await proxy.DoSomethingGreat();
### Using a weakly-typed client
Use the `Create` method to create a weakly-typed client like the following example. `Create` returns an instance of `ActorProxy`.
The following example uses the `Create` method to create a weakly-typed client. `Create` returns an instance of `ActorProxy`.
```csharp
// Create a proxy for type OtherActor with a random id
@ -76,9 +79,9 @@ var proxy = this.ProxyFactory.Create(ActorId.CreateRandom(), "OtherActor");
await proxy.InvokeMethodAsync("DoSomethingGreat");
```
Since `ActorProxy` is a weakly-typed proxy you need to pass in the actor method name as a string.
Since `ActorProxy` is a weakly-typed proxy, you need to pass in the actor method name as a string.
You can also use `ActorProxy` to invoke methods with a request message and response message. Request and response messages will be serialized using the `System.Text.Json` serializer.
You can also use `ActorProxy` to invoke methods with both a request and a response message. Request and response messages will be serialized using the `System.Text.Json` serializer.
```csharp
// Create a proxy for type OtherActor with a random id
@ -91,4 +94,21 @@ var request = new MyRequest() { Message = "Hi, it's me.", };
var response = await proxy.InvokeMethodAsync<MyRequest, MyResponse>("DoSomethingGreat", request);
```
When using a weakly-typed proxy, it is your responsibility to define the correct actor method names and message types. This is done for you when using a strongly-typed proxy since the names and types are part of the interface definition.
When using a weakly-typed proxy, you _must_ proactively define the correct actor method names and message types. When using a strongly-typed proxy, these names and types are defined for you as part of the interface definition.
### Actor method invocation exception details
The actor method invocation exception details are surfaced to the caller and the callee, providing an entry point to track down the issue. Exception details include:
- Method name
- Line number
- Exception type
- UUID
You use the UUID to match the exception on the caller and callee side. Below is an example of exception details:
```
Dapr.Actors.ActorMethodInvocationException: Remote Actor Method Exception, DETAILS: Exception: NotImplementedException, Method Name: ExceptionExample, Line Number: 14, Exception uuid: d291a006-84d5-42c4-b39e-d6300e9ac38b
```
## Next steps
[Learn how to author and run actors with `ActorHost`]({{< ref dotnet-actors-usage.md >}}).

View File

@ -1,22 +1,15 @@
---
type: docs
title: "Example of running and using virtual actors in the .NET SDK"
linkTitle: "Example"
title: "How to: Run and use virtual actors in the .NET SDK"
linkTitle: "How to: Run & use virtual actors"
weight: 300000
description: Try out .NET Dapr virtual actors with this example
---
The Dapr actor package allows you to interact with Dapr virtual actors from a .NET application.
The Dapr actor package allows you to interact with Dapr virtual actors from a .NET application. In this guide, you learn how to:
## Prerequisites
- [Dapr CLI]({{< ref install-dapr-cli.md >}}) installed
- Initialized [Dapr environment]({{< ref install-dapr-selfhost.md >}})
- [.NET Core 3.1 or .NET 5+](https://dotnet.microsoft.com/download) installed
## Overview
This document describes how to create an Actor (`MyActor`) and invoke its methods on the client application.
- Create an Actor (`MyActor`).
- Invoke its methods on the client application.
```
MyActor --- MyActor.Interfaces
@ -26,11 +19,41 @@ MyActor --- MyActor.Interfaces
+- MyActorClient
```
* **The interface project(\MyActor\MyActor.Interfaces).** This project contains the interface definition for the actor. Actor interfaces can be defined in any project with any name. The interface defines the actor contract that is shared by the actor implementation and the clients calling the actor. Because client projects may depend on it, it typically makes sense to define it in an assembly that is separate from the actor implementation.
**The interface project (\MyActor\MyActor.Interfaces)**
* **The actor service project(\MyActor\MyActorService).** This project implements ASP.Net Core web service that is going to host the actor. It contains the implementation of the actor, MyActor.cs. An actor implementation is a class that derives from the base type Actor and implements the interfaces defined in the MyActor.Interfaces project. An actor class must also implement a constructor that accepts an ActorService instance and an ActorId and passes them to the base Actor class.
This project contains the interface definition for the actor. Actor interfaces can be defined in any project with any name. The interface defines the actor contract shared by:
* **The actor client project(\MyActor\MyActorClient)** This project contains the implementation of the actor client which calls MyActor's method defined in Actor Interfaces.
- The actor implementation
- The clients calling the actor
Because client projects may depend on it, it's better to define it in an assembly separate from the actor implementation.
**The actor service project (\MyActor\MyActorService)**
This project implements the ASP.Net Core web service that hosts the actor. It contains the implementation of the actor, `MyActor.cs`. An actor implementation is a class that:
- Derives from the base type Actor
- Implements the interfaces defined in the `MyActor.Interfaces` project.
An actor class must also implement a constructor that accepts an `ActorService` instance and an `ActorId`, and passes them to the base Actor class.
**The actor client project (\MyActor\MyActorClient)**
This project contains the implementation of the actor client which calls MyActor's method defined in Actor Interfaces.
## Prerequisites
- [Dapr CLI]({{< ref install-dapr-cli.md >}}) installed.
- Initialized [Dapr environment]({{< ref install-dapr-selfhost.md >}}).
- [.NET 6](https://dotnet.microsoft.com/download), [.NET 8](https://dotnet.microsoft.com/download) or [.NET 9](https://dotnet.microsoft.com/download) installed
{{% alert title="Note" color="primary" %}}
Note that while .NET 6 is generally supported as the minimum .NET requirement across the Dapr .NET SDK packages
and .NET 7 is the minimally supported version of .NET by Dapr.Workflows in Dapr v1.15, only .NET 8 and .NET 9 will
continue to be supported by Dapr in v1.16 and later.
{{% /alert %}}
## Step 0: Prepare
@ -42,9 +65,9 @@ Actor interface defines the actor contract that is shared by the actor implement
Actor interface is defined with the below requirements:
* Actor interface must inherit `Dapr.Actors.IActor` interface
* The return type of Actor method must be `Task` or `Task<object>`
* Actor method can have one argument at a maximum
- Actor interface must inherit `Dapr.Actors.IActor` interface
- The return type of Actor method must be `Task` or `Task<object>`
- Actor method can have one argument at a maximum
### Create interface project and add dependencies
@ -55,7 +78,7 @@ dotnet new classlib -o MyActor.Interfaces
cd MyActor.Interfaces
# Add Dapr.Actors nuget package. Please use the latest package version from nuget.org
dotnet add package Dapr.Actors -v 1.0.0
dotnet add package Dapr.Actors
cd ..
```
@ -66,6 +89,7 @@ Define `IMyActor` interface and `MyData` data object. Paste the following code i
```csharp
using Dapr.Actors;
using Dapr.Actors.Runtime;
using System.Threading.Tasks;
namespace MyActor.Interfaces
@ -76,6 +100,7 @@ namespace MyActor.Interfaces
Task<MyData> GetDataAsync();
Task RegisterReminder();
Task UnregisterReminder();
Task<IActorReminder> GetReminder();
Task RegisterTimer();
Task UnregisterTimer();
}
@ -108,7 +133,7 @@ dotnet new web -o MyActorService
cd MyActorService
# Add Dapr.Actors.AspNetCore nuget package. Please use the latest package version from nuget.org
dotnet add package Dapr.Actors.AspNetCore -v 1.0.0
dotnet add package Dapr.Actors.AspNetCore
# Add Actor Interface reference
dotnet add reference ../MyActor.Interfaces/MyActor.Interfaces.csproj
@ -204,6 +229,14 @@ namespace MyActorService
TimeSpan.FromSeconds(5)); // Time interval between reminder invocations after the first invocation
}
/// <summary>
/// Get MyReminder reminder details with the actor
/// </summary>
public async Task<IActorReminder> GetReminder()
{
await this.GetReminderAsync("MyReminder");
}
/// <summary>
/// Unregister MyReminder reminder with the actor
/// </summary>
@ -291,22 +324,11 @@ namespace MyActorService
{
app.UseDeveloperExceptionPage();
}
else
{
// By default, ASP.Net Core uses port 5000 for HTTP. The HTTP
// redirection will interfere with the Dapr runtime. You can
// move this out of the else block if you use port 5001 in this
// example, and developer tooling (such as the VSCode extension).
app.UseHttpsRedirection();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
// Register actors handlers that interface with the Dapr runtime.
endpoints.MapActorsHandlers();
});
// Register actors handlers that interface with the Dapr runtime.
app.MapActorsHandlers();
}
}
}
@ -325,7 +347,7 @@ dotnet new console -o MyActorClient
cd MyActorClient
# Add Dapr.Actors nuget package. Please use the latest package version from nuget.org
dotnet add package Dapr.Actors -v 1.0.0
dotnet add package Dapr.Actors
# Add Actor Interface reference
dotnet add reference ../MyActor.Interfaces/MyActor.Interfaces.csproj
@ -377,7 +399,7 @@ namespace MyActorClient
Console.WriteLine($"Calling GetDataAsync on {actorType}:{actorId}...");
var savedData = await proxy.GetDataAsync();
Console.WriteLine($"Got response: {response}");
Console.WriteLine($"Got response: {savedData}");
}
}
}
@ -441,7 +463,7 @@ The projects that you've created can now to test the sample.
Calling SetDataAsync on MyActor:1...
Got response: Success
Calling GetDataAsync on MyActor:1...
Got response: Success
Got response: PropertyA: ValueA, PropertyB: ValueB
```
> 💡 This sample relies on a few assumptions. The default listening port for an ASP.NET Core web project is 5000, which is being passed to `dapr run` as `--app-port 5000`. The default HTTP port for the Dapr sidecar is 3500. We're telling the sidecar for `MyActorService` to use 3500 so that `MyActorClient` can rely on the default value.

View File

@ -0,0 +1,565 @@
---
type: docs
title: "Actor serialization in the .NET SDK"
linkTitle: "Actor serialization"
weight: 300000
description: Necessary steps to serialize your types using remoted Actors in .NET
---
# Actor Serialization
The Dapr actor package enables you to use Dapr virtual actors within a .NET application with either a weakly- or strongly-typed client. Each utilizes a different serialization approach. This document will review the differences and convey a few key ground rules to understand in either scenario.
Please be advised that it is not a supported scenario to use the weakly- or strongly typed actor clients interchangeably because of these different serialization approaches. The data persisted using one Actor client will not be accessible using the other Actor client, so it is important to pick one and use it consistently throughout your application.
## Weakly-typed Dapr Actor client
In this section, you will learn how to configure your C# types so they are properly serialized and deserialized at runtime when using a weakly-typed actor client. These clients use string-based names of methods with request and response payloads that are serialized using the System.Text.Json serializer. Please note that this serialization framework is not specific to Dapr and is separately maintained by the .NET team within the [.NET GitHub repository](https://github.com/dotnet/runtime/tree/main/src/libraries/System.Text.Json).
When using the weakly-typed Dapr Actor client to invoke methods from your various actors, it's not necessary to independently serialize or deserialize the method payloads as this will happen transparently on your behalf by the SDK.
The client will use the latest version of System.Text.Json available for the version of .NET you're building against and serialization is subject to all the inherent capabilities provided in the [associated .NET documentation](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/overview).
The serializer will be configured to use the `JsonSerializerOptions.Web` [default options](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/configure-options?pivots=dotnet-8-0#web-defaults-for-jsonserializeroptions) unless overridden with a custom options configuration which means the following are applied:
- Deserialization of the property name is performed in a case-insensitive manner
- Serialization of the property name is performed using [camel casing](https://en.wikipedia.org/wiki/Camel_case) unless the property is overridden with a `[JsonPropertyName]` attribute
- Deserialization will read numeric values from number and/or string values
### Basic Serialization
In the following example, we present a simple class named Doodad though it could just as well be a record as well.
```csharp
public class Doodad
{
public Guid Id { get; set; }
public string Name { get; set; }
public int Count { get; set; }
}
```
By default, this will serialize using the names of the members as used in the type and whatever values it was instantiated with:
```json
{"id": "a06ced64-4f42-48ad-84dd-46ae6a7e333d", "name": "DoodadName", "count": 5}
```
### Override Serialized Property Name
The default property names can be overridden by applying the `[JsonPropertyName]` attribute to desired properties.
Generally, this isn't going to be necessary for types you're persisting to the actor state as you're not intended to read or write them independent of Dapr-associated functionality, but
the following is provided just to clearly illustrate that it's possible.
#### Override Property Names on Classes
Here's an example demonstrating the use of `JsonPropertyName` to change the name for the first property following serialization. Note that the last usage of `JsonPropertyName` on the `Count` property
matches what it would be expected to serialize to. This is largely just to demonstrate that applying this attribute won't negatively impact anything - in fact, it might be preferable if you later
decide to change the default serialization options but still need to consistently access the properties previously serialized before that change as `JsonPropertyName` will override those options.
```csharp
public class Doodad
{
[JsonPropertyName("identifier")]
public Guid Id { get; set; }
public string Name { get; set; }
[JsonPropertyName("count")]
public int Count { get; set; }
}
```
This would serialize to the following:
```json
{"identifier": "a06ced64-4f42-48ad-84dd-46ae6a7e333d", "name": "DoodadName", "count": 5}
```
#### Override Property Names on Records
Let's try doing the same thing with a record from C# 12 or later:
```csharp
public record Thingy(string Name, [JsonPropertyName("count")] int Count);
```
Because the argument passed in a primary constructor (introduced in C# 12) can be applied to either a property or field within a record, using the `[JsonPropertyName]` attribute may
require specifying that you intend the attribute to apply to a property and not a field in some ambiguous cases. Should this be necessary, you'd indicate as much in the primary constructor with:
```csharp
public record Thingy(string Name, [property: JsonPropertyName("count")] int Count);
```
If `[property: ]` is applied to the `[JsonPropertyName]` attribute where it's not necessary, it will not negatively impact serialization or deserialization as the operation will
proceed normally as though it were a property (as it typically would if not marked as such).
### Enumeration types
Enumerations, including flat enumerations are serializable to JSON, but the value persisted may surprise you. Again, it's not expected that the developer should ever engage
with the serialized data independently of Dapr, but the following information may at least help in diagnosing why a seemingly mild version migration isn't working as expected.
Take the following `enum` type providing the various seasons in the year:
```csharp
public enum Season
{
Spring,
Summer,
Fall,
Winter
}
```
We'll go ahead and use a separate demonstration type that references our `Season` and simultaneously illustrate how this works with records:
```csharp
public record Engagement(string Name, Season TimeOfYear);
```
Given the following initialized instance:
```csharp
var myEngagement = new Engagement("Ski Trip", Season.Winter);
```
This would serialize to the following JSON:
```json
{"name": "Ski Trip", "season": 3}
```
That might be unexpected that our `Season.Winter` value was represented as a `3`, but this is because the serializer is going to automatically use numeric representations
of the enum values starting with zero for the first value and incrementing the numeric value for each additional value available. Again, if a migration were taking place and
a developer had flipped the order of the enums, this would affect a breaking change in your solution as the serialized numeric values would point to different values when deserialized.
Rather, there is a `JsonConverter` available with `System.Text.Json` that will instead opt to use a string-based value instead of the numeric value. The `[JsonConverter]` attribute needs
to be applied to be enum type itself to enable this, but will then be realized in any downstream serialization or deserialization operation that references the enum.
```csharp
[JsonConverter(typeof(JsonStringEnumConverter<Season>))]
public enum Season
{
Spring,
Summer,
Fall,
Winter
}
```
Using the same values from our `myEngagement` instance above, this would produce the following JSON instead:
```json
{"name": "Ski Trip", "season": "Winter"}
```
As a result, the enum members can be shifted around without fear of introducing errors during deserialization.
#### Custom Enumeration Values
The System.Text.Json serialization platform doesn't, out of the box, support the use of `[EnumMember]` to allow you to change the value of enum that's used during serialization or deserialization, but
there are scenarios where this could be useful. Again, assume that you're tasking with refactoring the solution to apply some better names to your various
enums. You're using the `JsonStringEnumConverter<TType>` detailed above so you're saving the name of the enum to value instead of a numeric value, but if you change
the enum name, that will introduce a breaking change as the name will no longer match what's in state.
Do note that if you opt into using this approach, you should decorate all your enum members with the `[EnumMeber]` attribute so that the values are consistently applied for each enum value instead
of haphazardly. Nothing will validate this at build or runtime, but it is considered a best practice operation.
How can you specify the precise value persisted while still changing the name of the enum member in this scenario? Use a custom `JsonConverter` with an extension method that can pull the value
out of the attached `[EnumMember]` attributes where provided. Add the following to your solution:
```csharp
public sealed class EnumMemberJsonConverter<T> : JsonConverter<T> where T : struct, Enum
{
/// <summary>Reads and converts the JSON to type <typeparamref name="T" />.</summary>
/// <param name="reader">The reader.</param>
/// <param name="typeToConvert">The type to convert.</param>
/// <param name="options">An object that specifies serialization options to use.</param>
/// <returns>The converted value.</returns>
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
// Get the string value from the JSON reader
var value = reader.GetString();
// Loop through all the enum values
foreach (var enumValue in Enum.GetValues<T>())
{
// Get the value from the EnumMember attribute, if any
var enumMemberValue = GetValueFromEnumMember(enumValue);
// If the values match, return the enum value
if (value == enumMemberValue)
{
return enumValue;
}
}
// If no match found, throw an exception
throw new JsonException($"Invalid value for {typeToConvert.Name}: {value}");
}
/// <summary>Writes a specified value as JSON.</summary>
/// <param name="writer">The writer to write to.</param>
/// <param name="value">The value to convert to JSON.</param>
/// <param name="options">An object that specifies serialization options to use.</param>
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
// Get the value from the EnumMember attribute, if any
var enumMemberValue = GetValueFromEnumMember(value);
// Write the value to the JSON writer
writer.WriteStringValue(enumMemberValue);
}
private static string GetValueFromEnumMember(T value)
{
MemberInfo[] member = typeof(T).GetMember(value.ToString(), BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public);
if (member.Length == 0)
return value.ToString();
object[] customAttributes = member.GetCustomAttributes(typeof(EnumMemberAttribute), false);
if (customAttributes.Length != 0)
{
EnumMemberAttribute enumMemberAttribute = (EnumMemberAttribute)customAttributes;
if (enumMemberAttribute != null && enumMemberAttribute.Value != null)
return enumMemberAttribute.Value;
}
return value.ToString();
}
}
```
Now let's add a sample enumerator. We'll set a value that uses the lower-case version of each enum member to demonstrate this. Don't forget to decorate the enum with the `JsonConverter`
attribute and reference our custom converter in place of the numeral-to-string converter used in the last section.
```csharp
[JsonConverter(typeof(EnumMemberJsonConverter<Season>))]
public enum Season
{
[EnumMember(Value="spring")]
Spring,
[EnumMember(Value="summer")]
Summer,
[EnumMember(Value="fall")]
Fall,
[EnumMember(Value="winter")]
Winter
}
```
Let's use our sample record from before. We'll also add a `[JsonPropertyName]` attribute just to augment the demonstration:
```csharp
public record Engagement([property: JsonPropertyName("event")] string Name, Season TimeOfYear);
```
And finally, let's initialize a new instance of this:
```csharp
var myEngagement = new Engagement("Conference", Season.Fall);
```
This time, serialization will take into account the values from the attached `[EnumMember]` attribute providing us a mechanism to refactor our application without necessitating
a complex versioning scheme for our existing enum values in the state.
```json
{"event": "Conference", "season": "fall"}
```
## Strongly-typed Dapr Actor client
In this section, you will learn how to configure your classes and records so they are properly serialized and deserialized at runtime when using a strongly-typed actor client. These clients are implemented using .NET interfaces and are <u>not</u> compatible with Dapr Actors written using other languages.
This actor client serializes data using an engine called the [Data Contract Serializer](https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/serializable-types) which converts your C# types to and from XML documents. This serialization framework is not specific to Dapr and is separately maintained by the .NET team within the [.NET GitHub repository](https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/DataContractSerializer.cs).
When sending or receiving primitives (like strings or ints), this serialization happens transparently and there's no requisite preparation needed on your part. However, when working with complex types such as those you create, there are some important rules to take into consideration so this process works smoothly.
### Serializable Types
There are several important considerations to keep in mind when using the Data Contract Serializer:
- By default, all types, read/write properties (after construction) and fields marked as publicly visible are serialized
- All types must either expose a public parameterless constructor or be decorated with the DataContractAttribute attribute
- Init-only setters are only supported with the use of the DataContractAttribute attribute
- Read-only fields, properties without a Get and Set method and internal or properties with private Get and Set methods are ignored during serialization
- Serialization is supported for types that use other complex types that are not themselves marked with the DataContractAttribute attribute through the use of the KnownTypesAttribute attribute
- If a type is marked with the DataContractAttribute attribute, all members you wish to serialize and deserialize must be decorated with the DataMemberAttribute attribute as well or they'll be set to their default values
### How does deserialization work?
The approach used for deserialization depends on whether or not the type is decorated with the [DataContractAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.serialization.datacontractattribute) attribute. If this attribute isn't present, an instance of the type is created using the parameterless constructor. Each of the properties and fields are then mapped into the type using their respective setters and the instance is returned to the caller.
If the type _is_ marked with `[DataContract]`, the serializer instead uses reflection to read the metadata of the type and determine which properties or fields should be included based on whether or not they're marked with the DataMemberAttribute attribute as it's performed on an opt-in basis. It then allocates an uninitialized object in memory (avoiding the use of any constructors, parameterless or not) and then sets the value directly on each mapped property or field, even if private or uses init-only setters. Serialization callbacks are invoked as applicable throughout this process and then the object is returned to the caller.
Use of the serialization attributes is highly recommended as they grant more flexibility to override names and namespaces and generally use more of the modern C# functionality. While the default serializer can be relied on for primitive types, it's not recommended for any of your own types, whether they be classes, structs or records. It's recommended that if you decorate a type with the DataContractAttribute attribute, you also explicitly decorate each of the members you want to serialize or deserialize with the DataMemberAttribute attribute as well.
#### .NET Classes
Classes are fully supported in the Data Contract Serializer provided that that other rules detailed on this page and the [Data Contract Serializer](https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/serializable-types) documentation are also followed.
The most important thing to remember here is that you must either have a public parameterless constructor or you must decorate it with the appropriate attributes. Let's review some examples to really clarify what will and won't work.
In the following example, we present a simple class named Doodad. We don't provide an explicit constructor here, so the compiler will provide an default parameterless constructor. Because we're using [supported primitive types](###supported-primitive-types) (Guid, string and int32) and all our members have a public getter and setter, no attributes are required and we'll be able to use this class without issue when sending and receiving it from a Dapr actor method.
```csharp
public class Doodad
{
public Guid Id { get; set; }
public string Name { get; set; }
public int Count { get; set; }
}
```
By default, this will serialize using the names of the members as used in the type and whatever values it was instantiated with:
```xml
<Doodad>
<Id>a06ced64-4f42-48ad-84dd-46ae6a7e333d</Id>
<Name>DoodadName</Name>
<Count>5</Count>
</Doodad>
```
So let's tweak it - let's add our own constructor and only use init-only setters on the members. This will fail to serialize and deserialize not because of the use of the init-only setters, but because there's no parameterless constructors.
```csharp
// WILL NOT SERIALIZE PROPERLY!
public class Doodad
{
public Doodad(string name, int count)
{
Id = Guid.NewGuid();
Name = name;
Count = count;
}
public Guid Id { get; set; }
public string Name { get; init; }
public int Count { get; init; }
}
```
If we add a public parameterless constructor to the type, we're good to go and this will work without further annotations.
```csharp
public class Doodad
{
public Doodad()
{
}
public Doodad(string name, int count)
{
Id = Guid.NewGuid();
Name = name;
Count = count;
}
public Guid Id { get; set; }
public string Name { get; set; }
public int Count { get; set; }
}
```
But what if we don't want to add this constructor? Perhaps you don't want your developers to accidentally create an instance of this Doodad using an unintended constructor. That's where the more flexible attributes are useful. If you decorate your type with a [DataContractAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.serialization.datacontractattribute) attribute, you can drop your parameterless constructor and it will work once again.
```csharp
[DataContract]
public class Doodad
{
public Doodad(string name, int count)
{
Id = Guid.NewGuid();
Name = name;
Count = count;
}
public Guid Id { get; set; }
public string Name { get; set; }
public int Count { get; set; }
}
```
In the above example, we don't need to also use the [DataMemberAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.serialization.datamemberattribute) attributes because again, we're using [built-in primitives](###supported-primitive-types) that the serializer supports. But, we do get more flexibility if we use the attributes. From the DataContractAttribute attribute, we can specify our own XML namespace with the Namespace argument and, via the Name argument, change the name of the type as used when serialized into the XML document.
It's a recommended practice to append the DataContractAttribute attribute to the type and the DataMemberAttribute attributes to all the members you want to serialize anyway - if they're not necessary and you're not changing the default values, they'll just be ignored, but they give you a mechanism to opt into serializing members that wouldn't otherwise have been included such as those marked as private or that are themselves complex types or collections.
Note that if you do opt into serializing your private members, their values will be serialized into plain text - they can very well be viewed, intercepted and potentially manipulated based on how you're handing the data once serialized, so it's an important consideration whether you want to mark these members or not in your use case.
In the following example, we'll look at using the attributes to change the serialized names of some of the members as well as introduce the [IgnoreDataMemberAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.serialization.ignoredatamemberattribute) attribute. As the name indicates, this tells the serializer to skip this property even though it'd be otherwise eligible to serialize. Further, because I'm decorating the type with the DataContractAttribute attribute, it means that I can use init-only setters on the properties.
```csharp
[DataContract(Name="Doodad")]
public class Doodad
{
public Doodad(string name = "MyDoodad", int count = 5)
{
Id = Guid.NewGuid();
Name = name;
Count = count;
}
[DataMember(Name = "id")]
public Guid Id { get; init; }
[IgnoreDataMember]
public string Name { get; init; }
[DataMember]
public int Count { get; init; }
}
```
When this is serialized, because we're changing the names of the serialized members, we can expect a new instance of Doodad using the default values this to be serialized as:
```xml
<Doodad>
<id>a06ced64-4f42-48ad-84dd-46ae6a7e333d</id>
<Count>5</Count>
</Doodad>
```
##### Classes in C# 12 - Primary Constructors
C# 12 brought us primary constructors on classes. Use of a primary constructor means the compiler will be prevented from creating the default implicit parameterless constructor. While a primary constructor on a class doesn't generate any public properties, it does mean that if you pass this primary constructor any arguments or have non-primitive types in your class, you'll either need to specify your own parameterless constructor or use the serialization attributes.
Here's an example where we're using the primary constructor to inject an ILogger to a field and add our own parameterless constructor without the need for any attributes.
```csharp
public class Doodad(ILogger<Doodad> _logger)
{
public Doodad() {} //Our parameterless constructor
public Doodad(string name, int count)
{
Id = Guid.NewGuid();
Name = name;
Count = count;
}
public Guid Id { get; set; }
public string Name { get; set; }
public int Count { get; set; }
}
```
And using our serialization attributes (again, opting for init-only setters since we're using the serialization attributes):
```csharp
[DataContract]
public class Doodad(ILogger<Doodad> _logger)
{
public Doodad(string name, int count)
{
Id = Guid.NewGuid();
Name = name;
Count = count;
}
[DataMember]
public Guid Id { get; init; }
[DataMember]
public string Name { get; init; }
[DataMember]
public int Count { get; init; }
}
```
#### .NET Structs
Structs are supported by the Data Contract serializer provided that they are marked with the DataContractAttribute attribute and the members you wish to serialize are marked with the DataMemberAttribute attribute. Further, to support deserialization, the struct will also need to have a parameterless constructor. This works even if you define your own parameterless constructor as enabled in C# 10.
```csharp
[DataContract]
public struct Doodad
{
[DataMember]
public int Count { get; set; }
}
```
#### .NET Records
Records were introduced in C# 9 and follow precisely the same rules as classes when it comes to serialization. We recommend that you should decorate all your records with the DataContractAttribute attribute and members you wish to serialize with DataMemberAttribute attributes so you don't experience any deserialization issues using this or other newer C# functionalities. Because record classes use init-only setters for properties by default and encourage the use of the primary constructor, applying these attributes to your types ensures that the serializer can properly otherwise accommodate your types as-is.
Typically records are presented as a simple one-line statement using the new primary constructor concept:
```csharp
public record Doodad(Guid Id, string Name, int Count);
```
This will throw an error encouraging the use of the serialization attributes as soon as you use it in a Dapr actor method invocation because there's no parameterless constructor available nor is it decorated with the aforementioned attributes.
Here we add an explicit parameterless constructor and it won't throw an error, but none of the values will be set during deserialization since they're created with init-only setters. Because this doesn't use the DataContractAttribute attribute or the DataMemberAttribute attribute on any members, the serializer will be unable to map the target members correctly during deserialization.
```csharp
public record Doodad(Guid Id, string Name, int Count)
{
public Doodad() {}
}
```
This approach does without the additional constructor and instead relies on the serialization attributes. Because we mark the type with the DataContractAttribute attribute and decorate each member with its own DataMemberAttribute attribute, the serialization engine will be able to map from the XML document to our type without issue.
```csharp
[DataContract]
public record Doodad(
[property: DataMember] Guid Id,
[property: DataMember] string Name,
[property: DataMember] int Count)
```
#### Supported Primitive Types
There are several types built into .NET that are considered primitive and eligible for serialization without additional effort on the part of the developer:
- [Byte](https://learn.microsoft.com/en-us/dotnet/api/system.byte)
- [SByte](https://learn.microsoft.com/en-us/dotnet/api/system.sbyte)
- [Int16](https://learn.microsoft.com/en-us/dotnet/api/system.int16)
- [Int32](https://learn.microsoft.com/en-us/dotnet/api/system.int32)
- [Int64](https://learn.microsoft.com/en-us/dotnet/api/system.int64)
- [UInt16](https://learn.microsoft.com/en-us/dotnet/api/system.uint16)
- [UInt32](https://learn.microsoft.com/en-us/dotnet/api/system.uint32)
- [UInt64](https://learn.microsoft.com/en-us/dotnet/api/system.uint64)
- [Single](https://learn.microsoft.com/en-us/dotnet/api/system.single)
- [Double](https://learn.microsoft.com/en-us/dotnet/api/system.double)
- [Boolean](https://learn.microsoft.com/en-us/dotnet/api/system.boolean)
- [Char](https://learn.microsoft.com/en-us/dotnet/api/system.char)
- [Decimal](https://learn.microsoft.com/en-us/dotnet/api/system.decimal)
- [Object](https://learn.microsoft.com/en-us/dotnet/api/system.object)
- [String](https://learn.microsoft.com/en-us/dotnet/api/system.string)
There are additional types that aren't actually primitives but have similar built-in support:
- [DateTime](https://learn.microsoft.com/en-us/dotnet/api/system.datetime)
- [TimeSpan](https://learn.microsoft.com/en-us/dotnet/api/system.timespan)
- [Guid](https://learn.microsoft.com/en-us/dotnet/api/system.guid)
- [Uri](https://learn.microsoft.com/en-us/dotnet/api/system.uri)
- [XmlQualifiedName](https://learn.microsoft.com/en-us/dotnet/api/system.xml.xmlqualifiedname)
Again, if you want to pass these types around via your actor methods, no additional consideration is necessary as they'll be serialized and deserialized without issue. Further, types that are themselves marked with the (SerializeableAttribute)[https://learn.microsoft.com/en-us/dotnet/api/system.serializableattribute] attribute will be serialized.
#### Enumeration Types
Enumerations, including flag enumerations are serializable if appropriately marked. The enum members you wish to be serialized must be marked with the [EnumMemberAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.serialization.enummemberattribute) attribute in order to be serialized. Passing a custom value into the optional Value argument on this attribute will allow you to specify the value used for the member in the serialized document instead of having the serializer derive it from the name of the member.
The enum type does not require that the type be decorated with the `DataContractAttribute` attribute - only that the members you wish to serialize be decorated with the `EnumMemberAttribute` attributes.
```csharp
public enum Colors
{
[EnumMember]
Red,
[EnumMember(Value="g")]
Green,
Blue, //Even if used by a type, this value will not be serialized as it's not decorated with the EnumMember attribute
}
```
#### Collection Types
With regards to the data contact serializer, all collection types that implement the [IEnumerable](https://learn.microsoft.com/en-us/dotnet/api/system.collections.ienumerable) interface including arays and generic collections are considered collections. Those types that implement [IDictionary](https://learn.microsoft.com/en-us/dotnet/api/system.collections.idictionary) or the generic [IDictionary<TKey, TValue>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.idictionary-2) are considered dictionary collections; all others are list collections.
Not unlike other complex types, collection types must have a parameterless constructor available. Further, they must also have a method called Add so they can be properly serialized and deserialized. The types used by these collection types must themselves be marked with the `DataContractAttribute` attribute or otherwise be serializable as described throughout this document.
#### Data Contract Versioning
As the data contract serializer is only used in Dapr with respect to serializing the values in the .NET SDK to and from the Dapr actor instances via the proxy methods, there's little need to consider versioning of data contracts as the data isn't being persisted between application versions using the same serializer. For those interested in learning more about data contract versioning visit [here](https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/data-contract-versioning).
#### Known Types
Nesting your own complex types is easily accommodated by marking each of the types with the [DataContractAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.serialization.datacontractattribute) attribute. This informs the serializer as to how deserialization should be performed.
But what if you're working with polymorphic types and one of your members is a base class or interface with derived classes or other implementations? Here, you'll use the [KnownTypeAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.serialization.knowntypeattribute) attribute to give a hint to the serializer about how to proceed.
When you apply the [KnownTypeAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.serialization.knowntypeattribute) attribute to a type, you are informing the data contract serializer about what subtypes it might encounter allowing it to properly handle the serialization and deserialization of these types, even when the actual type at runtime is different from the declared type.
```chsarp
[DataContract]
[KnownType(typeof(DerivedClass))]
public class BaseClass
{
//Members of the base class
}
[DataContract]
public class DerivedClass : BaseClass
{
//Additional members of the derived class
}
```
In this example, the `BaseClass` is marked with `[KnownType(typeof(DerivedClass))]` which tells the data contract serializer that `DerivedClass` is a possible implementation of `BaseClass` that it may need to serialize or deserialize. Without this attribute, the serialize would not be aware of the `DerivedClass` when it encounters an instance of `BaseClass` that is actually of type `DerivedClass` and this could lead to a serialization exception because the serializer would not know how to handle the derived type. By specifying all possible derived types as known types, you ensure that the serializer can process the type and its members correctly.
For more information and examples about using `[KnownType]`, please refer to the [official documentation](https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/data-contract-known-types).

View File

@ -1,16 +1,21 @@
---
type: docs
title: "Dapr actor .NET usage guide"
title: "Author & run actors"
linkTitle: "Authoring actors"
weight: 200000
description: Learn all about authoring and running actors with the .NET SDK
---
## Authoring actors
## Author actors
### ActorHost
The `ActorHost` is a required constructor parameter of all actors, and must be passed to the base class constructor.
The `ActorHost`:
- Is a required constructor parameter of all actors
- Is provided by the runtime
- Must be passed to the base class constructor
- Contains all of the state that allows that actor instance to communicate with the runtime
```csharp
internal class MyActor : Actor, IMyActor, IRemindable
@ -22,11 +27,11 @@ internal class MyActor : Actor, IMyActor, IRemindable
}
```
The `ActorHost` is provided by the runtime and contains all of the state that the allows that actor instance to communicate with the runtime. Since the `ActorHost` contains state unique to the actor, you should not pass the instance into other parts of your code. You should not create your own instances of `ActorHost` except in tests.
Since the `ActorHost` contains state unique to the actor, you don't need to pass the instance into other parts of your code. It's recommended only create your own instances of `ActorHost` in tests.
### Using dependency injection
### Dependency injection
Actors support [depenendency injection](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection) of additional parameters into the constructor. Any other parameters your define will have their values satisfied from the dependency injection container.
Actors support [dependency injection](https://docs.microsoft.com/aspnet/core/fundamentals/dependency-injection) of additional parameters into the constructor. Any other parameters you define will have their values satisfied from the dependency injection container.
```csharp
internal class MyActor : Actor, IMyActor, IRemindable
@ -39,9 +44,9 @@ internal class MyActor : Actor, IMyActor, IRemindable
}
```
An actor type should have a single `public` constructor. The actor infrastructure uses the [ActivatorUtilities](https://docs.microsoft.com/en-us/dotnet/core/extensions/dependency-injection#constructor-injection-behavior) pattern for constructing actor instances.
An actor type should have a single `public` constructor. The actor infrastructure uses the [`ActivatorUtilities`](https://docs.microsoft.com/en-us/dotnet/core/extensions/dependency-injection#constructor-injection-behavior) pattern for constructing actor instances.
You can register types with dependency injection in `Startup.cs` to make them available. You can read more about the different ways of registering your types [here](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?#service-registration-methods)
You can register types with dependency injection in `Startup.cs` to make them available. Read more about [the different ways of registering your types](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?#service-registration-methods).
```csharp
// In Startup.cs
@ -54,7 +59,7 @@ public void ConfigureServices(IServiceCollection services)
}
```
Each actor instance has its own dependency injection scope. Each actor remains in memory for some time after performing an operation, and during that time the dependency injection scope associated with the actor is also considered live. The scope will be releases when the actor is deactivated.
Each actor instance has its own dependency injection scope and remains in memory for some time after performing an operation. During that time, the dependency injection scope associated with the actor is also considered live. The scope will be released when the actor is deactivated.
If an actor injects an `IServiceProvider` in the constructor, the actor will receive a reference to the `IServiceProvider` associated with its scope. The `IServiceProvider` can be used to resolve services dynamically in the future.
@ -69,17 +74,17 @@ internal class MyActor : Actor, IMyActor, IRemindable
}
```
When using this pattern, take care to avoid creating many instances of **transient** services which implement `IDisposable`. Since the scope associated with an actor could be considered valid for a long time, it is possible to accumulate many services in memory. See the [dependency injection guidelines](https://docs.microsoft.com/en-us/dotnet/core/extensions/dependency-injection-guidelines) for more information.
When using this pattern, avoid creating many instances of **transient** services which implement `IDisposable`. Since the scope associated with an actor could be considered valid for a long time, you can accumulate many services in memory. See the [dependency injection guidelines](https://docs.microsoft.com/en-us/dotnet/core/extensions/dependency-injection-guidelines) for more information.
### IDisposable and actors
Actors can implement `IDisposable` or `IAsyncDisposable`. It is recommended that you rely on dependency injection for resource management rather than implementing dispose functionality in application code. Dispose support is provided for the rare case where it is truly necessary.
Actors can implement `IDisposable` or `IAsyncDisposable`. It's recommended that you rely on dependency injection for resource management rather than implementing dispose functionality in application code. Dispose support is provided in the rare case where it is truly necessary.
### Logging
Inside of an actor class you have access to an instance of `ILogger` through a property on the base `Actor` class. This instance is connected to the ASP.NET Core logging system, and should be used for all logging inside an actor. Read more about logging [here](https://docs.microsoft.com/en-us/dotnet/core/extensions/logging?tabs=command-line). You can configure a variety of different logging formats and output sinks.
Inside an actor class, you have access to an `ILogger` instance through a property on the base `Actor` class. This instance is connected to the ASP.NET Core logging system and should be used for all logging inside an actor. Read more about [logging](https://docs.microsoft.com/en-us/dotnet/core/extensions/logging?tabs=command-line). You can configure a variety of different logging formats and output sinks.
You should use *structured logging* with *named placeholders* like the example below:
Use _structured logging_ with _named placeholders_ like the example below:
```csharp
public Task<MyData> GetDataAsync()
@ -91,11 +96,11 @@ public Task<MyData> GetDataAsync()
When logging, avoid using format strings like: `$"Getting state at {DateTime.UtcNow}"`
Logging should use the [named placeholder syntax](https://docs.microsoft.com/en-us/dotnet/core/extensions/logging?tabs=command-line#log-message-template) which is more performant and offers better integration with logging systems.
Logging should use the [named placeholder syntax](https://docs.microsoft.com/dotnet/core/extensions/logging?tabs=command-line#log-message-template) which offers better performance and integration with logging systems.
### Using an explicit actor type name
By default, the *type* of the actor as seen by clients is derived from the name of the actor implementation class. The default name will be the class name name (without namespace).
By default, the _type_ of the actor, as seen by clients, is derived from the _name_ of the actor implementation class. The default name will be the class name (without namespace).
If desired, you can specify an explicit type name by attaching an `ActorAttribute` attribute to the actor implementation class.
@ -107,15 +112,15 @@ internal class MyActor : Actor, IMyActor
}
```
In the example above the name will be `MyCustomActorTypeName`.
In the example above, the name will be `MyCustomActorTypeName`.
No change is needed to the code that registers the actor type with the runtime, providing the value via the attribute is all that is required.
## Hosting actors on the server
## Host actors on the server
### Registering actors
Actor registration is part `ConfigureServices` in `Startup.cs`. The `ConfigureServices` method is where services are registered with dependency injection, and registering the set of actor types is part of the registration of actor services.
Actor registration is part of `ConfigureServices` in `Startup.cs`. You can register services with dependency injection via the `ConfigureServices` method. Registering the set of actor types is part of the registration of actor services.
Inside `ConfigureServices` you can:
@ -148,9 +153,12 @@ public void ConfigureServices(IServiceCollection services)
### Configuring JSON options
The actor runtime uses [System.Text.Json](https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-overview) for serializing data to the state store, and for handling requests from the weakly-typed client.
The actor runtime uses [System.Text.Json](https://docs.microsoft.com/dotnet/standard/serialization/system-text-json-overview) for:
By default the actor runtime uses settings based on [JsonSerializerDefaults.Web](https://docs.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializerdefaults?view=net-5.0)
- Serializing data to the state store
- Handling requests from the weakly-typed client
By default, the actor runtime uses settings based on [JsonSerializerDefaults.Web](https://docs.microsoft.com/dotnet/api/system.text.json.jsonserializerdefaults?view=net-5.0).
You can configure the `JsonSerializerOptions` as part of `ConfigureServices`:
@ -193,7 +201,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
}
```
The `UseRouting` and `UseEndpoints` calls are necessary to configure routing. Adding `MapActorsHandlers` inside the endpoint middleware is what configures actors as part of the pipeline.
The `UseRouting` and `UseEndpoints` calls are necessary to configure routing. Configure actors as part of the pipeline by adding `MapActorsHandlers` inside the endpoint middleware.
This is a minimal example, it's valid for Actors functionality to existing alongside:
@ -206,7 +214,7 @@ This is a minimal example, it's valid for Actors functionality to existing along
### Problematic middleware
Certain middleware may interfere with the routing of Dapr requests to the actors handlers. In particular the `UseHttpsRedirection` is problematic for the default configuration of Dapr. Dapr will send requests over unencrypted HTTP by default, which will then be blocked by the `UseHttpsRedirection` middleware. This middleware cannot be used with Dapr at this time.
Certain middleware may interfere with the routing of Dapr requests to the actors handlers. In particular, the `UseHttpsRedirection` is problematic for Dapr's default configuration. Dapr sends requests over unencrypted HTTP by default, which the `UseHttpsRedirection` middleware will block. This middleware cannot be used with Dapr at this time.
```csharp
// in Startup.cs
@ -229,4 +237,8 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
endpoints.MapActorsHandlers();
});
}
```
```
## Next steps
Try the [Running and using virtual actors example]({{< ref dotnet-actors-howto.md >}}).

View File

@ -0,0 +1,12 @@
---
type: docs
title: "Dapr AI .NET SDK"
linkTitle: "AI"
weight: 50000
description: Get up and running with the Dapr AI .NET SDK
---
With the Dapr AI package, you can interact with the Dapr AI workloads from a .NET application.
Today, Dapr provides the Conversational API to engage with large language models. To get started with this workload,
walk through the [Dapr Conversational AI]({{< ref dotnet-ai-conversation-howto.md >}}) how-to guide.

View File

@ -0,0 +1,90 @@
---
type: docs
title: "How to: Create and use Dapr AI Conversations in the .NET SDK"
linkTitle: "How to: Use the AI Conversations client"
weight: 500100
description: Learn how to create and use the Dapr Conversational AI client using the .NET SDK
---
## Prerequisites
- [.NET 6](https://dotnet.microsoft.com/download/dotnet/6.0), [.NET 8](https://dotnet.microsoft.com/download/dotnet/8.0), or [.NET 9](https://dotnet.microsoft.com/download/dotnet/9.0) installed
- [Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/)
- [Initialized Dapr environment](https://docs.dapr.io/getting-started/install-dapr-selfhost)
{{% alert title="Note" color="primary" %}}
.NET 6 is supported as the minimum required for the Dapr .NET SDK packages in this release. Only .NET 8 and .NET 9
will be supported in Dapr v1.16 and later releases.
{{% /alert %}}
## Installation
To get started with the Dapr AI .NET SDK client, install the [Dapr.AI package](https://www.nuget.org/packages/Dapr.AI) from NuGet:
```sh
dotnet add package Dapr.AI
```
A `DaprConversationClient` maintains access to networking resources in the form of TCP sockets used to communicate with the Dapr sidecar.
### Dependency Injection
The `AddDaprAiConversation()` method will register the Dapr client ASP.NET Core dependency injection and is the recommended approach
for using this package. This method accepts an optional options delegate for configuring the `DaprConversationClient` and a
`ServiceLifetime` argument, allowing you to specify a different lifetime for the registered services instead of the default `Singleton`
value.
The following example assumes all default values are acceptable and is sufficient to register the `DaprConversationClient`:
```csharp
services.AddDaprAiConversation();
```
The optional configuration delegate is used to configure the `DaprConversationClient` by specifying options on the
`DaprConversationClientBuilder` as in the following example:
```csharp
services.AddSingleton<DefaultOptionsProvider>();
services.AddDaprAiConversation((serviceProvider, clientBuilder) => {
//Inject a service to source a value from
var optionsProvider = serviceProvider.GetRequiredService<DefaultOptionsProvider>();
var standardTimeout = optionsProvider.GetStandardTimeout();
//Configure the value on the client builder
clientBuilder.UseTimeout(standardTimeout);
});
```
### Manual Instantiation
Rather than using dependency injection, a `DaprConversationClient` can also be built using the static client builder.
For best performance, create a single long-lived instance of `DaprConversationClient` and provide access to that shared instance throughout
your application. `DaprConversationClient` instances are thread-safe and intended to be shared.
Avoid creating a `DaprConversationClient` per-operation.
A `DaprConversationClient` can be configured by invoking methods on the `DaprConversationClientBuilder` class before calling `.Build()`
to create the client. The settings for each `DaprConversationClient` are separate and cannot be changed after calling `.Build()`.
```csharp
var daprConversationClient = new DaprConversationClientBuilder()
.UseJsonSerializerSettings( ... ) //Configure JSON serializer
.Build();
```
See the .NET [documentation here]({{< ref dotnet-client >}}) for more information about the options available when configuring the Dapr client via the builder.
## Try it out
Put the Dapr AI .NET SDK to the test. Walk through the samples to see Dapr in action:
| SDK Samples | Description |
| ----------- | ----------- |
| [SDK samples](https://github.com/dapr/dotnet-sdk/tree/master/examples) | Clone the SDK repo to try out some examples and get started. |
## Building Blocks
This part of the .NET SDK allows you to interface with the Conversations API to send and receive messages from
large language models.
### Send messages

View File

@ -0,0 +1,135 @@
---
type: docs
title: "Dapr AI Client"
linkTitle: "AI client"
weight: 50005
description: Learn how to create Dapr AI clients
---
The Dapr AI client package allows you to interact with the AI capabilities provided by the Dapr sidecar.
## Lifetime management
A `DaprConversationClient` is a version of the Dapr client that is dedicated to interacting with the Dapr Conversation
API. It can be registered alongside a `DaprClient` and other Dapr clients without issue.
It maintains access to networking resources in the form of TCP sockets used to communicate with the Dapr sidecar.
For best performance, create a single long-lived instance of `DaprConversationClient` and provide access to that shared
instance throughout your application. `DaprConversationClient` instances are thread-safe and intended to be shared.
This can be aided by utilizing the dependency injection functionality. The registration method supports registration using
as a singleton, a scoped instance or as transient (meaning it's recreated every time it's injected), but also enables
registration to utilize values from an `IConfiguration` or other injected service in a way that's impractical when
creating the client from scratch in each of your classes.
Avoid creating a `DaprConversationClient` for each operation.
## Configuring DaprConversationClient via DaprConversationClientBuilder
A `DaprConversationClient` can be configured by invoking methods on the `DaprConversationClientBuilder` class before
calling `.Build()` to create the client itself. The settings for each `DaprConversationClient` are separate
and cannot be changed after calling `.Build()`.
```cs
var daprConversationClient = new DaprConversationClientBuilder()
.UseDaprApiToken("abc123") // Specify the API token used to authenticate to other Dapr sidecars
.Build();
```
The `DaprConversationClientBuilder` contains settings for:
- The HTTP endpoint of the Dapr sidecar
- The gRPC endpoint of the Dapr sidecar
- The `JsonSerializerOptions` object used to configure JSON serialization
- The `GrpcChannelOptions` object used to configure gRPC
- The API token used to authenticate requests to the sidecar
- The factory method used to create the `HttpClient` instance used by the SDK
- The timeout used for the `HttpClient` instance when making requests to the sidecar
The SDK will read the following environment variables to configure the default values:
- `DAPR_HTTP_ENDPOINT`: used to find the HTTP endpoint of the Dapr sidecar, example: `https://dapr-api.mycompany.com`
- `DAPR_GRPC_ENDPOINT`: used to find the gRPC endpoint of the Dapr sidecar, example: `https://dapr-grpc-api.mycompany.com`
- `DAPR_HTTP_PORT`: if `DAPR_HTTP_ENDPOINT` is not set, this is used to find the HTTP local endpoint of the Dapr sidecar
- `DAPR_GRPC_PORT`: if `DAPR_GRPC_ENDPOINT` is not set, this is used to find the gRPC local endpoint of the Dapr sidecar
- `DAPR_API_TOKEN`: used to set the API token
### Configuring gRPC channel options
Dapr's use of `CancellationToken` for cancellation relies on the configuration of the gRPC channel options. If you need
to configure these options yourself, make sure to enable the [ThrowOperationCanceledOnCancellation setting](https://grpc.github.io/grpc/csharp-dotnet/api/Grpc.Net.Client.GrpcChannelOptions.html#Grpc_Net_Client_GrpcChannelOptions_ThrowOperationCanceledOnCancellation).
```cs
var daprConversationClient = new DaprConversationClientBuilder()
.UseGrpcChannelOptions(new GrpcChannelOptions { ... ThrowOperationCanceledOnCancellation = true })
.Build();
```
## Using cancellation with `DaprConversationClient`
The APIs on `DaprConversationClient` perform asynchronous operations and accept an optional `CancellationToken` parameter. This
follows a standard .NET practice for cancellable operations. Note that when cancellation occurs, there is no guarantee that
the remote endpoint stops processing the request, only that the client has stopped waiting for completion.
When an operation is cancelled, it will throw an `OperationCancelledException`.
## Configuring `DaprConversationClient` via dependency injection
Using the built-in extension methods for registering the `DaprConversationClient` in a dependency injection container can
provide the benefit of registering the long-lived service a single time, centralize complex configuration and improve
performance by ensuring similarly long-lived resources are re-purposed when possible (e.g. `HttpClient` instances).
There are three overloads available to give the developer the greatest flexibility in configuring the client for their
scenario. Each of these will register the `IHttpClientFactory` on your behalf if not already registered, and configure
the `DaprConversationClientBuilder` to use it when creating the `HttpClient` instance in order to re-use the same instance as
much as possible and avoid socket exhaustion and other issues.
In the first approach, there's no configuration done by the developer and the `DaprConversationClient` is configured with the
default settings.
```cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDaprConversationClient(); //Registers the `DaprConversationClient` to be injected as needed
var app = builder.Build();
```
Sometimes the developer will need to configure the created client using the various configuration options detailed
above. This is done through an overload that passes in the `DaprConversationClientBuiler` and exposes methods for configuring
the necessary options.
```cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDaprConversationClient((_, daprConversationClientBuilder) => {
//Set the API token
daprConversationClientBuilder.UseDaprApiToken("abc123");
//Specify a non-standard HTTP endpoint
daprConversationClientBuilder.UseHttpEndpoint("http://dapr.my-company.com");
});
var app = builder.Build();
```
Finally, it's possible that the developer may need to retrieve information from another service in order to populate
these configuration values. That value may be provided from a `DaprClient` instance, a vendor-specific SDK or some
local service, but as long as it's also registered in DI, it can be injected into this configuration operation via the
last overload:
```cs
var builder = WebApplication.CreateBuilder(args);
//Register a fictional service that retrieves secrets from somewhere
builder.Services.AddSingleton<SecretService>();
builder.Services.AddDaprConversationClient((serviceProvider, daprConversationClientBuilder) => {
//Retrieve an instance of the `SecretService` from the service provider
var secretService = serviceProvider.GetRequiredService<SecretService>();
var daprApiToken = secretService.GetSecret("DaprApiToken").Value;
//Configure the `DaprConversationClientBuilder`
daprConversationClientBuilder.UseDaprApiToken(daprApiToken);
});
var app = builder.Build();
```

View File

@ -9,11 +9,11 @@ no_list: true
The Dapr client package allows you to interact with other Dapr applications from a .NET application.
## Prerequisites
{{% alert title="Note" color="primary" %}}
If you haven't already, [try out one of the quickstarts]({{< ref quickstarts >}}) for a quick walk-through on how to use the Dapr .NET SDK with an API building block.
{{% /alert %}}
- [Dapr CLI]({{< ref install-dapr-cli.md >}}) installed
- Initialized [Dapr environment]({{< ref install-dapr-selfhost.md >}})
- [.NET Core 3.1 or .NET 5+](https://dotnet.microsoft.com/download) installed
## Building blocks
@ -21,13 +21,22 @@ The .NET SDK allows you to interface with all of the [Dapr building blocks]({{<
### Invoke a service
#### HTTP
You can either use the `DaprClient` or `System.Net.Http.HttpClient` to invoke your services.
{{% alert title="Note" color="primary" %}}
You can also [invoke a non-Dapr endpoint using either a named `HTTPEndpoint` or an FQDN URL to the non-Dapr environment]({{< ref "howto-invoke-non-dapr-endpoints.md#using-an-httpendpoint-resource-or-fqdn-url-for-non-dapr-endpoints" >}}).
{{% /alert %}}
{{< tabs SDK HTTP>}}
{{% codetab %}}
```csharp
using var client = new DaprClientBuilder().Build();
using var client = new DaprClientBuilder().
UseTimeout(TimeSpan.FromSeconds(2)). // Optionally, set a timeout
Build();
// Invokes a POST method named "deposit" that takes input of type "Transaction"
var data = new { id = "17", amount = 99m };
@ -40,15 +49,31 @@ Console.WriteLine("Returned: id:{0} | Balance:{1}", account.Id, account.Balance)
```csharp
var client = DaprClient.CreateInvokeHttpClient(appId: "routing");
// To set a timeout on the HTTP client:
client.Timeout = TimeSpan.FromSeconds(2);
var deposit = new Transaction { Id = "17", Amount = 99m };
var response = await client.PostAsJsonAsync("/deposit", deposit, cancellationToken);
var account = await response.Content.ReadFromJsonAsync<Account>(cancellationToken: cancellationToken);
Console.WriteLine("Returned: id:{0} | Balance:{1}", account.Id, account.Balance);
```
{{% /codetab %}}
{{< /tabs >}}
#### gRPC
You can use the `DaprClient` to invoke your services over gRPC.
```csharp
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(20));
var invoker = DaprClient.CreateInvocationInvoker(appId: myAppId, daprEndpoint: serviceEndpoint);
var client = new MyService.MyServiceClient(invoker);
var options = new CallOptions(cancellationToken: cts.Token, deadline: DateTime.UtcNow.AddSeconds(1));
await client.MyMethodAsync(new Empty(), options);
Assert.Equal(StatusCode.DeadlineExceeded, ex.StatusCode);
```
- For a full guide on service invocation visit [How-To: Invoke a service]({{< ref howto-invoke-discover-services.md >}}).
### Save & get application state
@ -67,6 +92,31 @@ await client.DeleteStateAsync(storeName, stateKeyName, cancellationToken: cancel
Console.WriteLine("Deleted State!");
```
### Query State (Alpha)
```csharp
var query = "{" +
"\"filter\": {" +
"\"EQ\": { \"value.Id\": \"1\" }" +
"}," +
"\"sort\": [" +
"{" +
"\"key\": \"value.Balance\"," +
"\"order\": \"DESC\"" +
"}" +
"]" +
"}";
var client = new DaprClientBuilder().Build();
var queryResponse = await client.QueryStateAsync<Account>("querystore", query, cancellationToken: cancellationToken);
Console.WriteLine($"Got {queryResponse.Results.Count}");
foreach (var account in queryResponse.Results)
{
Console.WriteLine($"Account: {account.Data.Id} has {account.Data.Balance}");
}
```
- For a full list of state operations visit [How-To: Get & save state]({{< ref howto-get-save-state.md >}}).
### Publish messages
@ -80,7 +130,7 @@ Console.WriteLine("Published deposit event!");
```
- For a full list of state operations visit [How-To: Publish & subscribe]({{< ref howto-publish-subscribe.md >}}).
- Visit [.NET SDK examples](https://github.com/dapr/dotnet-sdk/tree/master/examples/client/PublishSubscribe) for code samples and instructions to try out pub/sub
- Visit [.NET SDK examples](https://github.com/dapr/dotnet-sdk/tree/master/examples/Client/PublishSubscribe) for code samples and instructions to try out pub/sub
### Interact with output bindings
@ -116,7 +166,7 @@ var secrets = await client.GetSecretAsync("mysecretstore", "key-value-pair-secre
Console.WriteLine($"Got secret keys: {string.Join(", ", secrets.Keys)}");
```
{{% / codetab %}}
{{% /codetab %}}
{{% codetab %}}
@ -140,5 +190,151 @@ Console.WriteLine("Got a secret value, I'm not going to be print it, it's a secr
- For a full guide on secrets visit [How-To: Retrieve secrets]({{< ref howto-secrets.md >}}).
### Get Configuration Keys
```csharp
var client = new DaprClientBuilder().Build();
// Retrieve a specific set of keys.
var specificItems = await client.GetConfiguration("configstore", new List<string>() { "key1", "key2" });
Console.WriteLine($"Here are my values:\n{specificItems[0].Key} -> {specificItems[0].Value}\n{specificItems[1].Key} -> {specificItems[1].Value}");
// Retrieve all configuration items by providing an empty list.
var specificItems = await client.GetConfiguration("configstore", new List<string>());
Console.WriteLine($"I got {configItems.Count} entires!");
foreach (var item in configItems)
{
Console.WriteLine($"{item.Key} -> {item.Value}")
}
```
### Subscribe to Configuration Keys
```csharp
var client = new DaprClientBuilder().Build();
// The Subscribe Configuration API returns a wrapper around an IAsyncEnumerable<IEnumerable<ConfigurationItem>>.
// Iterate through it by accessing its Source in a foreach loop. The loop will end when the stream is severed
// or if the cancellation token is cancelled.
var subscribeConfigurationResponse = await daprClient.SubscribeConfiguration(store, keys, metadata, cts.Token);
await foreach (var items in subscribeConfigurationResponse.Source.WithCancellation(cts.Token))
{
foreach (var item in items)
{
Console.WriteLine($"{item.Key} -> {item.Value}")
}
}
```
### Distributed lock (Alpha)
#### Acquire a lock
```csharp
using System;
using Dapr.Client;
namespace LockService
{
class Program
{
[Obsolete("Distributed Lock API is in Alpha, this can be removed once it is stable.")]
static async Task Main(string[] args)
{
var daprLockName = "lockstore";
var fileName = "my_file_name";
var client = new DaprClientBuilder().Build();
// Locking with this approach will also unlock it automatically, as this is a disposable object
await using (var fileLock = await client.Lock(DAPR_LOCK_NAME, fileName, "random_id_abc123", 60))
{
if (fileLock.Success)
{
Console.WriteLine("Success");
}
else
{
Console.WriteLine($"Failed to lock {fileName}.");
}
}
}
}
}
```
#### Unlock an existing lock
```csharp
using System;
using Dapr.Client;
namespace LockService
{
class Program
{
static async Task Main(string[] args)
{
var daprLockName = "lockstore";
var client = new DaprClientBuilder().Build();
var response = await client.Unlock(DAPR_LOCK_NAME, "my_file_name", "random_id_abc123"));
Console.WriteLine(response.status);
}
}
}
```
## Sidecar APIs
### Sidecar Health
The .NET SDK provides a way to poll for the sidecar health, as well as a convenience method to wait for the sidecar to be ready.
#### Poll for health
This health endpoint returns true when both the sidecar and your application are up (fully initialized).
```csharp
var client = new DaprClientBuilder().Build();
var isDaprReady = await client.CheckHealthAsync();
if (isDaprReady)
{
// Execute Dapr dependent code.
}
```
#### Poll for health (outbound)
This health endpoint returns true when Dapr has initialized all its components, but may not have finished setting up a communication channel with your application.
This is best used when you want to utilize a Dapr component in your startup path, for instance, loading secrets from a secretstore.
```csharp
var client = new DaprClientBuilder().Build();
var isDaprComponentsReady = await client.CheckOutboundHealthAsync();
if (isDaprComponentsReady)
{
// Execute Dapr component dependent code.
}
```
#### Wait for sidecar
The `DaprClient` also provides a helper method to wait for the sidecar to become healthy (components only). When using this method, it is recommended to include a `CancellationToken` to
allow for the request to timeout. Below is an example of how this is used in the `DaprSecretStoreConfigurationProvider`.
```csharp
// Wait for the Dapr sidecar to report healthy before attempting use Dapr components.
using (var tokenSource = new CancellationTokenSource(sidecarWaitTimeout))
{
await client.WaitForSidecarAsync(tokenSource.Token);
}
// Perform Dapr component operations here i.e. fetching secrets.
```
### Shutdown the sidecar
```csharp
var client = new DaprClientBuilder().Build();
await client.ShutdownSidecarAsync();
```
## Related links
- [.NET SDK examples](https://github.com/dapr/dotnet-sdk/tree/master/examples)

View File

@ -10,6 +10,48 @@ description: Essential tips and advice for using DaprClient
A `DaprClient` holds access to networking resources in the form of TCP sockets used to communicate with the Dapr sidecar. `DaprClient` implements `IDisposable` to support eager cleanup of resources.
### Dependency Injection
The `AddDaprClient()` method will register the Dapr client with ASP.NET Core dependency injection. This method accepts an optional
options delegate for configuring the `DaprClient` and an `ServiceLifetime` argument, allowing you to specify a different lifetime
for the registered resources instead of the default `Singleton` value.
The following example assumes all default values are acceptable and is sufficient to register the `DaprClient`.
```csharp
services.AddDaprClient();
```
The optional configuration delegates are used to configure `DaprClient` by specifying options on the provided `DaprClientBuilder`
as in the following example:
```csharp
services.AddDaprClient(daprBuilder => {
daprBuilder.UseJsonSerializerOptions(new JsonSerializerOptions {
WriteIndented = true,
MaxDepth = 8
});
daprBuilder.UseTimeout(TimeSpan.FromSeconds(30));
});
```
The another optional configuration delegate overload provides access to both the `DaprClientBuilder` as well as an `IServiceProvider`
allowing for more advanced configurations that may require injecting services from the dependency injection container.
```csharp
services.AddSingleton<SampleService>();
services.AddDaprClient((serviceProvider, daprBuilder) => {
var sampleService = serviceProvider.GetRequiredService<SampleService>();
var timeoutValue = sampleService.TimeoutOptions;
daprBuilder.UseTimeout(timeoutValue);
});
```
### Manual Instantiation
Rather than using dependency injection, a `DaprClient` can also be built using the static client builder.
For best performance, create a single long-lived instance of `DaprClient` and provide access to that shared instance throughout your application. `DaprClient` instances are thread-safe and intended to be shared.
Avoid creating a `DaprClient` per-operation and disposing it when the operation is complete.
@ -24,23 +66,58 @@ var daprClient = new DaprClientBuilder()
.Build();
```
The `DaprClientBuilder` contains settings for:
By default, the `DaprClientBuilder` will prioritize the following locations, in the following order, to source the configuration
values:
- The HTTP endpoint of the Dapr sidecar
- The gRPC endpoint of the Dapr sidecar
- The `JsonSerializerOptions` object used to configure JSON serialization
- The `GrpcChannelOptions` object used to configure gRPC
- The API Token used to authenticate requests to the sidecar
- The value provided to a method on the `DaprClientBuilder` (e.g. `UseTimeout(TimeSpan.FromSeconds(30))`)
- The value pulled from an optionally injected `IConfiguration` matching the name expected in the associated environment variable
- The value pulled from the associated environment variable
- Default values
### Configuring on `DaprClientBuilder`
The `DaprClientBuilder` contains the following methods to set configuration options:
- `UseHttpEndpoint(string)`: The HTTP endpoint of the Dapr sidecar
- `UseGrpcEndpoint(string)`: Sets the gRPC endpoint of the Dapr sidecar
- `UseGrpcChannelOptions(GrpcChannelOptions)`: Sets the gRPC channel options used to connect to the Dapr sidecar
- `UseHttpClientFactory(IHttpClientFactory)`: Configures the DaprClient to use a registered `IHttpClientFactory` when building `HttpClient` instances
- `UseJsonSerializationOptions(JsonSerializerOptions)`: Used to configure JSON serialization
- `UseDaprApiToken(string)`: Adds the provided token to every request to authenticate to the Dapr sidecar
- `UseTimeout(TimeSpan)`: Specifies a timeout value used by the `HttpClient` when communicating with the Dapr sidecar
### Configuring From `IConfiguration`
Rather than rely on sourcing configuration values directly from environment variables or because the values are sourced
from dependency injected services, another options is to make these values available on `IConfiguration`.
For example, you might be registering your application in a multi-tenant environment and need to prefix the environment
variables used. The following example shows how these values can be sourced from the environment variables to your
`IConfiguration` when their keys are prefixed with `test_`;
```csharp
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddEnvironmentVariables("test_"); //Retrieves all environment variables that start with "test_" and removes the prefix when sourced from IConfiguration
builder.Services.AddDaprClient();
```
### Configuring From Environment Variables
The SDK will read the following environment variables to configure the default values:
- `DAPR_HTTP_PORT`: used to find the HTTP endpoint of the Dapr sidecar
- `DAPR_GRPC_PORT`: used to find the gRPC endpoint of the Dapr sidecar
- `DAPR_HTTP_ENDPOINT`: used to find the HTTP endpoint of the Dapr sidecar, example: `https://dapr-api.mycompany.com`
- `DAPR_GRPC_ENDPOINT`: used to find the gRPC endpoint of the Dapr sidecar, example: `https://dapr-grpc-api.mycompany.com`
- `DAPR_HTTP_PORT`: if `DAPR_HTTP_ENDPOINT` is not set, this is used to find the HTTP local endpoint of the Dapr sidecar
- `DAPR_GRPC_PORT`: if `DAPR_GRPC_ENDPOINT` is not set, this is used to find the gRPC local endpoint of the Dapr sidecar
- `DAPR_API_TOKEN`: used to set the API Token
{{% alert title="Note" color="primary" %}}
If both `DAPR_HTTP_ENDPOINT` and `DAPR_HTTP_PORT` are specified, the port value from `DAPR_HTTP_PORT` will be ignored in favor of the port
implicitly or explicitly defined on `DAPR_HTTP_ENDPOINT`. The same is true of both `DAPR_GRPC_ENDPOINT` and `DAPR_GRPC_PORT`.
{{% /alert %}}
### Configuring gRPC channel options
Dapr's use of `CancellationToken` for cancellation relies on the configuration of the gRPC channel options. If you need to configure these options yourself, make sure to enable the [ThrowOperationCanceledOnCancellation setting](https://grpc.github.io/grpc/csharp-dotnet/api/Grpc.Net.Client.GrpcChannelOptions.html#Grpc_Net_Client_GrpcChannelOptions_ThrowOperationCanceledOnCancellation).
Dapr's use of `CancellationToken` for cancellation relies on the configuration of the gRPC channel options and this is enabled by default. If you need to configure these options yourself, make sure to enable the [ThrowOperationCanceledOnCancellation setting](https://grpc.github.io/grpc/csharp-dotnet/api/Grpc.Net.Client.GrpcChannelOptions.html#Grpc_Net_Client_GrpcChannelOptions_ThrowOperationCanceledOnCancellation).
```C#
var daprClient = new DaprClientBuilder()
@ -56,7 +133,7 @@ When an operation is cancelled, it will throw an `OperationCancelledException`.
## Understanding DaprClient JSON serialization
Many method on `DaprClient` perform JSON serialization using the `System.Text.Json` serializer. Methods that accept an application data type as an argument will JSON serialize it, unless the documentation clearly states otherwise.
Many methods on `DaprClient` perform JSON serialization using the `System.Text.Json` serializer. Methods that accept an application data type as an argument will JSON serialize it, unless the documentation clearly states otherwise.
It is worth reading the [System.Text.Json documentation](https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-overview) if you have advanced requirements. The Dapr .NET SDK provides no unique serialization behavior or customizations - it relies on the underlying serializer to convert data to and from the application's .NET types.

View File

@ -2,13 +2,13 @@
type: docs
title: "Developing applications with the Dapr .NET SDK"
linkTitle: "Dev integrations"
weight: 50000
weight: 100000
description: Learn about local development integration options for .NET Dapr applications
---
## Thinking more than one at a time
Using your favorite IDE or editor to launch an application typically assumes that you only need to run one thing - the application you are debugging. However, developing microservices challenges you think about your local development process for *more than one at a time*. A microservices application has multiple services that you might need running at the same time as well as dependencies like state stores to manage.
Using your favorite IDE or editor to launch an application typically assumes that you only need to run one thing: the application you're debugging. However, developing microservices challenges you to think about your local development process for *more than one at a time*. A microservices application has multiple services that you might need running simultaneously, and dependencies (like state stores) to manage.
Adding Dapr to your development process means you need to manage the following concerns:
@ -18,7 +18,7 @@ Adding Dapr to your development process means you need to manage the following c
- Additional dependencies such as state stores
- optional: the Dapr placement service for actors
This document will assume that you're building a production application, and want to create a repeatable and robust set of development practices. The guidance here is general, and applies to any .NET server application using Dapr (including actors).
This document assumes that you're building a production application, and want to create a repeatable and robust set of development practices. The guidance here is general, and applies to any .NET server application using Dapr (including actors).
## Managing components

View File

@ -0,0 +1,138 @@
---
type: docs
title: "Dapr .NET SDK Development with .NET Aspire"
linkTitle: ".NET Aspire"
weight: 40000
description: Learn about local development with .NET Aspire
---
# .NET Aspire
[.NET Aspire](https://learn.microsoft.com/en-us/dotnet/aspire/get-started/aspire-overview) is a development tool
designed to make it easier to include external software into .NET applications by providing a framework that allows
third-party services to be readily integrated, observed and provisioned alongside your own software.
Aspire simplifies local development by providing rich integration with popular IDEs including
[Microsoft Visual Studio](https://visualstudio.microsoft.com/vs/),
[Visual Studio Code](https://code.visualstudio.com/),
[JetBrains Rider](https://blog.jetbrains.com/dotnet/2024/02/19/jetbrains-rider-and-the-net-aspire-plugin/) and others
to launch your application with the debugger while automatically launching and provisioning access to other
integrations as well, including Dapr.
While Aspire also assists with deployment of your application to various cloud hosts like Microsoft Azure and
Amazon AWS, deployment is currently outside the scope of this guide. More information can be found in Aspire's
documentation [here](https://learn.microsoft.com/en-us/dotnet/aspire/deployment/overview).
## Prerequisites
- While the Dapr .NET SDK is compatible with [.NET 6](https://dotnet.microsoft.com/download/dotnet/6.0),
[.NET 8](https://dotnet.microsoft.com/download/dotnet/8.0) or [.NET 9](https://dotnet.microsoft.com/download/dotnet/9.0),
.NET Aspire is only compatible with [.NET 8](https://dotnet.microsoft.com/download/dotnet/8.0) or
[.NET 9](https://dotnet.microsoft.com/download/dotnet/9.0).
- An OCI compliant container runtime such as [Docker Desktop](https://www.docker.com/products/docker-desktop) or
[Podman](https://podman.io/)
- Install and initialize Dapr v1.13 or later
## Using .NET Aspire via CLI
We'll start by creating a brand new .NET application. Open your preferred CLI and navigate to the directory you wish
to create your new .NET solution within. Start by using the following command to install a template that will create
an empty Aspire application:
```sh
dotnet new install Aspire.ProjectTemplates
```
Once that's installed, proceed to create an empty .NET Aspire application in your current directory. The `-n` argument
allows you to specify the name of the output solution. If it's excluded, the .NET CLI will instead use the name
of the output directory, e.g. `C:\source\aspiredemo` will result in the solution being named `aspiredemo`. The rest
of this tutorial will assume a solution named `aspiredemo`.
```sh
dotnet new aspire -n aspiredemo
```
This will create two Aspire-specific directories and one file in your directory:
- `aspiredemo.AppHost/` contains the Aspire orchestration project that is used to configure each of the integrations
used in your application(s).
- `aspiredemo.ServiceDefaults/` contains a collection of extensions meant to be shared across your solution to aid in
resilience, service discovery and telemetry capabilities offered by Aspire (these are distinct from the capabilities
offered in Dapr itself).
- `aspiredemo.sln` is the file that maintains the layout of your current solution
We'll next create a project that'll serve as our Dapr application. From the same directory, use the following
to create an empty ASP.NET Core project called `MyApp`. This will be created relative to your current directory in
`MyApp\MyApp.csproj`.
```sh
dotnet new web MyApp
```
Next we'll configure the AppHost project to add the necessary package to support local Dapr development. Navigate
into the AppHost directory with the following and install the `Aspire.Hosting.Dapr` package from NuGet into the project.
We'll also add a reference to our `MyApp` project so we can reference it during the registration process.
```sh
cd aspiredemo.AppHost
dotnet add package Aspire.Hosting.Dapr
dotnet add reference ../MyApp/
```
Next, we need to configure Dapr as a resource to be loaded alongside your project. Open the `Program.cs` file in that
project within your preferred IDE. It should look similar to the following:
```csharp
var builder = DistributedApplication.CreateBuilder(args);
builder.Build().Run();
```
If you're familiar with the dependency injection approach used in ASP.NET Core projects or others utilizing the
`Microsoft.Extensions.DependencyInjection` functionality, you'll find that this will be a familiar experience.
Because we've already added a project reference to `MyApp`, we need to start by adding a reference in this configuration
as well. Add the following before the `builder.Build().Run()` line:
```csharp
var myApp = builder
.AddProject<Projects.MyApp>("myapp")
.WithDaprSidecar();
```
Because the project reference has been added to this solution, your project shows up as a type within the `Projects.`
namespace for our purposes here. The name of the variable you assign the project to doesn't much matter in this tutorial
but would be used if you wanted to create a reference between this project and another using Aspire's service discovery
functionality.
Adding `.WithDaprSidecar()` configures Dapr as a .NET Aspire resource so that when the project runs, the sidecar will be
deployed alongside your application. This accepts a number of different options and could optionally be configured as in
the following example:
```csharp
DaprSidecarOptions sidecarOptions = new()
{
AppId = "my-other-app",
AppPort = 8080, //Note that this argument is required if you intend to configure pubsub, actors or workflows as of Aspire v9.0
DaprGrpcPort = 50001,
DaprHttpPort = 3500,
MetricsPort = 9090
};
builder
.AddProject<Projects.MyOtherApp>("myotherapp")
.WithReference(myApp)
.WithDaprSidecar(sidecarOptions);
```
{{% alert color="primary" %}}
As indicated in the example above, as of .NET Aspire 9.0, if you intend to use any functionality in which Dapr needs to
call into your application such as pubsub, actors or workflows, you will need to specify your AppPort as
a configured option as Aspire will not automatically pass it to Dapr at runtime. It's expected that this behavior will
change in a future release as a fix has been merged and can be tracked [here](https://github.com/dotnet/aspire/pull/6362).
{{% /alert %}}
When you open the solution in your IDE, ensure that the `aspiredemo.AppHost` is configured as your startup project, but
when you launch it in a debug configuration, you'll note that your integrated console should reflect your expected Dapr
logs and it will be available to your application.

View File

@ -8,7 +8,7 @@ description: Learn about local development with the Dapr CLI
## Dapr CLI
*Consider this to be a .NET companion to the [Dapr Self-Hosted with Docker Guide]({{ ref self-hosted-overview.md }}))*.
*Consider this to be a .NET companion to the [Dapr Self-Hosted with Docker Guide]({{< ref self-hosted-with-docker.md >}})*.
The Dapr CLI provides you with a good base to work from by initializing a local redis container, zipkin container, the placement service, and component manifests for redis. This will enable you to work with the following building blocks on a fresh install with no additional setup:

View File

@ -2,13 +2,13 @@
type: docs
title: "Dapr .NET SDK Development with Docker-Compose"
linkTitle: "Docker Compose"
weight: 50000
weight: 60000
description: Learn about local development with Docker-Compose
---
## Docker-Compose
*Consider this to be a .NET companion to the [Dapr Self-Hosted with Docker Guide]({{ ref self-hosted-with-docker.md }}))*.
*Consider this to be a .NET companion to the [Dapr Self-Hosted with Docker Guide]({{< ref self-hosted-with-docker.md >}})*.
`docker-compose` is a CLI tool included with Docker Desktop that you can use to run multiple containers at a time. It is a way to automate the lifecycle of multiple containers together, and offers a development experience similar to a production environment for applications targeting Kubernetes.

View File

@ -2,7 +2,7 @@
type: docs
title: "Dapr .NET SDK Development with Project Tye"
linkTitle: "Project Tye"
weight: 40000
weight: 50000
description: Learn about local development with Project Tye
---

View File

@ -0,0 +1,7 @@
---
type: docs
title: "Error Handling in the Dapr .NET SDK"
linkTitle: "Error handling"
weight: 90000
description: Learn about error handling in the Dapr.NET SDK.
---

View File

@ -0,0 +1,140 @@
---
type: docs
title: "Richer Error Model in the Dapr .NET SDK"
linkTitle: "Richer error model"
weight: 59000
description: Learn how to use the richer error model in the .NET SDK.
---
The Dapr .NET SDK supports the richer error model, implemented by the Dapr runtime. This model provides a way for applications to enrich their errors with added context,
allowing consumers of the application to better understand the issue and resolve faster. You can read more about the richer error model [here](https://google.aip.dev/193), and you
can find the Dapr proto file implementing these errors [here](https://github.com/googleapis/googleapis/blob/master/google/rpc/error_details.proto").
The Dapr .NET SDK implements all details supported by the Dapr runtime, implemented in the `Dapr.Common.Exceptions` namespace, and is accessible through
the `DaprException` extension method `TryGetExtendedErrorInfo`. Currently this detail extraction is only supported for
`RpcException`'s where the details are present.
```csharp
// Example usage of ExtendedErrorInfo
try
{
// Perform some action with the Dapr client that throws a DaprException.
}
catch (DaprException daprEx)
{
if (daprEx.TryGetExtendedErrorInfo(out DaprExtendedErrorInfo errorInfo)
{
Console.WriteLine(errorInfo.Code);
Console.WriteLine(errorInfo.Message);
foreach (DaprExtendedErrorDetail detail in errorInfo.Details)
{
Console.WriteLine(detail.ErrorType);
switch (detail.ErrorType)
case ExtendedErrorType.ErrorInfo:
Console.WriteLine(detail.Reason);
Console.WriteLine(detail.Domain);
default:
Console.WriteLine(detail.TypeUrl);
}
}
}
```
## DaprExtendedErrorInfo
Contains `Code` (the status code) and `Message` (the error message) associated with the error, parsed from an inner `RpcException`.
Also contains a collection of `DaprExtendedErrorDetails` parsed from the details in the exception.
## DaprExtendedErrorDetail
All details implement the abstract `DaprExtendedErrorDetail` and have an associated `DaprExtendedErrorType`.
1. [RetryInfo](#retryinfo)
2. [DebugInfo](#debuginfo)
3. [QuotaFailure](#quotafailure)
4. [PreconditionFailure](#preconditionfailure)
5. [RequestInfo](#requestinfo)
6. [LocalizedMessage](#localizedmessage)
7. [BadRequest](#badrequest)
8. [ErrorInfo](#errorinfo)
9. [Help](#help)
10. [ResourceInfo](#resourceinfo)
11. [Unknown](#unknown)
## RetryInfo
Information telling the client how long to wait before they should retry. Provides a `DaprRetryDelay` with the properties
`Second` (offset in seconds) and `Nano` (offset in nanoseconds).
## DebugInfo
Debugging information offered by the server. Contains `StackEntries` (a collection of strings containing the stack trace), and
`Detail` (further debugging information).
## QuotaFailure
Information relating to some quota that may have been reached, such as a daily usage limit on an API. It has one property `Violations`,
a collection of `DaprQuotaFailureViolation`, which each contain a `Subject` (the subject of the request) and `Description` (further information regarding the failure).
## PreconditionFailure
Information informing the client that some required precondition was not met. Has one property `Violations`, a collection of
`DaprPreconditionFailureViolation`, which each has `Subject` (subject where the precondition failure occured e.g. "Azure"), `Type` (representation of the precondition type e.g. "TermsOfService"), and `Description` (further description e.g. "ToS must be accepted.").
## RequestInfo
Information returned by the server that can be used by the server to identify the clients request. Contains
`RequestId` and `ServingData` properties, `RequestId` being some string (such as a UID) the server can interpret,
and `ServingData` being some arbitrary data that made up part of the request.
## LocalizedMessage
Contains a localized message, along with the locale of the message. Contains `Locale` (the locale e.g. "en-US") and `Message` (the localized message).
## BadRequest
Describes a bad request field. Contains collection of `DaprBadRequestDetailFieldViolation`, which each has `Field` (the offending field in request e.g. 'first_name') and
`Description` (further information detailing the reason e.g. "first_name cannot contain special characters").
## ErrorInfo
Details the cause of an error. Contains three properties, `Reason` (the reason for the error, which should take the form of UPPER_SNAKE_CASE e.g. DAPR_INVALID_KEY),
`Domain` (domain the error belongs to e.g. 'dapr.io'), and `Metadata`, a key value based collection of futher information.
## Help
Provides resources for the client to perform further research into the issue. Contains a collection of `DaprHelpDetailLink`,
which provides `Url` (a url to help or documentation), and `Description` (a description of what the link provides).
## ResourceInfo
Provides information relating to an accessed resource. Provides three properties `ResourceType` (type of the resource being access e.g. "Azure service bus"),
`ResourceName` (The name of the resource e.g. "my-configured-service-bus"), `Owner` (the owner of the resource e.g. "subscriptionowner@dapr.io"),
and `Description` (further information on the resource relating to the error e.g. "missing permissions to use this resource").
## Unknown
Returned when the detail type url cannot be mapped to the correct `DaprExtendedErrorDetail` implementation.
Provides one property `TypeUrl` (the type url that could not be parsed e.g. "type.googleapis.com/Google.rpc.UnrecognizedType").

View File

@ -0,0 +1,13 @@
---
type: docs
title: "Dapr Jobs .NET SDK"
linkTitle: "Jobs"
weight: 50000
description: Get up and running with Dapr Jobs and the Dapr .NET SDK
---
With the Dapr Job package, you can interact with the Dapr Job APIs from a .NET application to trigger future operations
to run according to a predefined schedule with an optional payload.
To get started, walk through the [Dapr Jobs]({{< ref dotnet-jobs-howto.md >}}) how-to guide and refer to
[best practices documentation]({{< ref dotnet-jobsclient-usage.md >}}) for additional guidance.

View File

@ -0,0 +1,394 @@
---
type: docs
title: "How to: Author and manage Dapr Jobs in the .NET SDK"
linkTitle: "How to: Author & manage jobs"
weight: 51000
description: Learn how to author and manage Dapr Jobs using the .NET SDK
---
Let's create an endpoint that will be invoked by Dapr Jobs when it triggers, then schedule the job in the same app. We'll use the [simple example provided here](https://github.com/dapr/dotnet-sdk/tree/master/examples/Jobs), for the following demonstration and walk through it as an explainer of how you can schedule one-time or recurring jobs using either an interval or Cron expression yourself. In this guide,
you will:
- Deploy a .NET Web API application ([JobsSample](https://github.com/dapr/dotnet-sdk/tree/master/examples/Jobs/JobsSample))
- Utilize the Dapr .NET Jobs SDK to schedule a job invocation and set up the endpoint to be triggered
In the .NET example project:
- The main [`Program.cs`](https://github.com/dapr/dotnet-sdk/tree/master/examples/Jobs/JobsSample/Program.cs) file comprises the entirety of this demonstration.
## Prerequisites
- [Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/)
- [Initialized Dapr environment](https://docs.dapr.io/getting-started/install-dapr-selfhost)
- [.NET 6](https://dotnet.microsoft.com/download/dotnet/6.0), [.NET 8](https://dotnet.microsoft.com/download/dotnet/8.0) or [.NET 9](https://dotnet.microsoft.com/download/dotnet/9.0) installed
- [Dapr.Jobs](https://www.nuget.org/packages/Dapr.Jobs) NuGet package installed to your project
{{% alert title="Note" color="primary" %}}
Note that while .NET 6 is the minimum support version of .NET in Dapr v1.15, only .NET 8 and .NET 9 will continue to be supported by Dapr in v1.16 and later.
{{% /alert %}}
## Set up the environment
Clone the [.NET SDK repo](https://github.com/dapr/dotnet-sdk).
```sh
git clone https://github.com/dapr/dotnet-sdk.git
```
From the .NET SDK root directory, navigate to the Dapr Jobs example.
```sh
cd examples/Jobs
```
## Run the application locally
To run the Dapr application, you need to start the .NET program and a Dapr sidecar. Navigate to the `JobsSample` directory.
```sh
cd JobsSample
```
We'll run a command that starts both the Dapr sidecar and the .NET program at the same time.
```sh
dapr run --app-id jobsapp --dapr-grpc-port 4001 --dapr-http-port 3500 -- dotnet run
```
> Dapr listens for HTTP requests at `http://localhost:3500` and internal Jobs gRPC requests at `http://localhost:4001`.
## Register the Dapr Jobs client with dependency injection
The Dapr Jobs SDK provides an extension method to simplify the registration of the Dapr Jobs client. Before completing
the dependency injection registration in `Program.cs`, add the following line:
```cs
var builder = WebApplication.CreateBuilder(args);
//Add anywhere between these two lines
builder.Services.AddDaprJobsClient();
var app = builder.Build();
```
> Note that in today's implementation of the Jobs API, the app that schedules the job will also be the app that receives the trigger notification. In other words, you cannot schedule a trigger to run in another application. As a result, while you don't explicitly need the Dapr Jobs client to be registered in your application to schedule a trigger invocation endpoint, your endpoint will never be invoked without the same app also scheduling the job somehow (whether via this Dapr Jobs .NET SDK or an HTTP call to the sidecar).
It's possible that you may want to provide some configuration options to the Dapr Jobs client that
should be present with each call to the sidecar such as a Dapr API token, or you want to use a non-standard
HTTP or gRPC endpoint. This is possible through use of an overload of the registration method that allows configuration of a
`DaprJobsClientBuilder` instance:
```cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDaprJobsClient((_, daprJobsClientBuilder) =>
{
daprJobsClientBuilder.UseDaprApiToken("abc123");
daprJobsClientBuilder.UseHttpEndpoint("http://localhost:8512"); //Non-standard sidecar HTTP endpoint
});
var app = builder.Build();
```
Still, it's possible that whatever values you wish to inject need to be retrieved from some other source, itself registered as a dependency. There's one more overload you can use to inject an `IServiceProvider` into the configuration action method. In the following example, we register a fictional singleton that can retrieve secrets from somewhere and pass it into the configuration method for `AddDaprJobClient` so
we can retrieve our Dapr API token from somewhere else for registration here:
```cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<SecretRetriever>();
builder.Services.AddDaprJobsClient((serviceProvider, daprJobsClientBuilder) =>
{
var secretRetriever = serviceProvider.GetRequiredService<SecretRetriever>();
var daprApiToken = secretRetriever.GetSecret("DaprApiToken").Value;
daprJobsClientBuilder.UseDaprApiToken(daprApiToken);
daprJobsClientBuilder.UseHttpEndpoint("http://localhost:8512");
});
var app = builder.Build();
```
## Use the Dapr Jobs client using IConfiguration
It's possible to configure the Dapr Jobs client using the values in your registered `IConfiguration` as well without
explicitly specifying each of the value overrides using the `DaprJobsClientBuilder` as demonstrated in the previous
section. Rather, by populating an `IConfiguration` made available through dependency injection the `AddDaprJobsClient()`
registration will automatically use these values over their respective defaults.
Start by populating the values in your configuration. This can be done in several different ways as demonstrated below.
### Configuration via `ConfigurationBuilder`
Application settings can be configured without using a configuration source and by instead populating the value in-memory
using a `ConfigurationBuilder` instance:
```csharp
var builder = WebApplication.CreateBuilder();
//Create the configuration
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string> {
{ "DAPR_HTTP_ENDPOINT", "http://localhost:54321" },
{ "DAPR_API_TOKEN", "abc123" }
})
.Build();
builder.Configuration.AddConfiguration(configuration);
builder.Services.AddDaprJobsClient(); //This will automatically populate the HTTP endpoint and API token values from the IConfiguration
```
### Configuration via Environment Variables
Application settings can be accessed from environment variables available to your application.
The following environment variables will be used to populate both the HTTP endpoint and API token used to register the
Dapr Jobs client.
| Key | Value |
| --- | --- |
| DAPR_HTTP_ENDPOINT | http://localhost:54321 |
| DAPR_API_TOKEN | abc123 |
```csharp
var builder = WebApplication.CreateBuilder();
builder.Configuration.AddEnvironmentVariables();
builder.Services.AddDaprJobsClient();
```
The Dapr Jobs client will be configured to use both the HTTP endpoint `http://localhost:54321` and populate all outbound
requests with the API token header `abc123`.
### Configuration via prefixed Environment Variables
However, in shared-host scenarios where there are multiple applications all running on the same machine without using
containers or in development environments, it's not uncommon to prefix environment variables. The following example
assumes that both the HTTP endpoint and the API token will be pulled from environment variables prefixed with the
value "myapp_". The two environment variables used in this scenario are as follows:
| Key | Value |
| --- | --- |
| myapp_DAPR_HTTP_ENDPOINT | http://localhost:54321 |
| myapp_DAPR_API_TOKEN | abc123 |
These environment variables will be loaded into the registered configuration in the following example and made available
without the prefix attached.
```csharp
var builder = WebApplication.CreateBuilder();
builder.Configuration.AddEnvironmentVariables(prefix: "myapp_");
builder.Services.AddDaprJobsClient();
```
The Dapr Jobs client will be configured to use both the HTTP endpoint `http://localhost:54321` and populate all outbound
requests with the API token header `abc123`.
## Use the Dapr Jobs client without relying on dependency injection
While the use of dependency injection simplifies the use of complex types in .NET and makes it easier to
deal with complicated configurations, you're not required to register the `DaprJobsClient` in this way. Rather, you can also elect to create an instance of it from a `DaprJobsClientBuilder` instance as demonstrated below:
```cs
public class MySampleClass
{
public void DoSomething()
{
var daprJobsClientBuilder = new DaprJobsClientBuilder();
var daprJobsClient = daprJobsClientBuilder.Build();
//Do something with the `daprJobsClient`
}
}
```
## Set up a endpoint to be invoked when the job is triggered
It's easy to set up a jobs endpoint if you're at all familiar with [minimal APIs in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis/overview) as the syntax is the same between the two.
Once dependency injection registration has been completed, configure the application the same way you would to handle mapping an HTTP request via the minimal API functionality in ASP.NET Core. Implemented as an extension method,
pass the name of the job it should be responsive to and a delegate. Services can be injected into the delegate's arguments as you wish and the job payload can be accessed from the `ReadOnlyMemory<byte>` originally provided to the
job registration.
There are two delegates you can use here. One provides an `IServiceProvider` in case you need to inject other services into the handler:
```cs
//We have this from the example above
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDaprJobsClient();
var app = builder.Build();
//Add our endpoint registration
app.MapDaprScheduledJob("myJob", (IServiceProvider serviceProvider, string jobName, ReadOnlyMemory<byte> jobPayload) => {
var logger = serviceProvider.GetService<ILogger>();
logger?.LogInformation("Received trigger invocation for '{jobName}'", "myJob");
//Do something...
});
app.Run();
```
The other overload of the delegate doesn't require an `IServiceProvider` if not necessary:
```cs
//We have this from the example above
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDaprJobsClient();
var app = builder.Build();
//Add our endpoint registration
app.MapDaprScheduledJob("myJob", (string jobName, ReadOnlyMemory<byte> jobPayload) => {
//Do something...
});
app.Run();
```
## Support cancellation tokens when processing mapped invocations
You may want to ensure that timeouts are handled on job invocations so that they don't indefinitely hang and use system resources. When setting up the job mapping, there's an optional `TimeSpan` parameter that can be
provided as the last argument to specify a timeout for the request. Every time the job mapping invocation is triggered, a new `CancellationTokenSource` will be created using this timeout parameter and a `CancellationToken`
will be created from it to put an upper bound on the processing of the request. If a timeout isn't provided, this defaults to `CancellationToken.None` and a timeout will not be automatically applied to the mapping.
```cs
//We have this from the example above
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDaprJobsClient();
var app = builder.Build();
//Add our endpoint registration
app.MapDaprScheduledJob("myJob", (string jobName, ReadOnlyMemory<byte> jobPayload) => {
//Do something...
}, TimeSpan.FromSeconds(15)); //Assigns a maximum timeout of 15 seconds for handling the invocation request
app.Run();
```
## Register the job
Finally, we have to register the job we want scheduled. Note that from here, all SDK methods have cancellation token support and use a default token if not otherwise set.
There are three different ways to set up a job that vary based on how you want to configure the schedule:
### One-time job
A one-time job is exactly that; it will run at a single point in time and will not repeat. This approach requires that you select a job name and specify a time it should be triggered.
| Argument Name | Type | Description | Required |
|---|---|---|---|
| jobName | string | The name of the job being scheduled. | Yes |
| scheduledTime | DateTime | The point in time when the job should be run. | Yes |
| payload | ReadOnlyMemory<byte> | Job data provided to the invocation endpoint when triggered. | No |
| cancellationToken | CancellationToken | Used to cancel out of the operation early, e.g. because of an operation timeout. | No |
One-time jobs can be scheduled from the Dapr Jobs client as in the following example:
```cs
public class MyOperation(DaprJobsClient daprJobsClient)
{
public async Task ScheduleOneTimeJobAsync(CancellationToken cancellationToken)
{
var today = DateTime.UtcNow;
var threeDaysFromNow = today.AddDays(3);
await daprJobsClient.ScheduleOneTimeJobAsync("myJobName", threeDaysFromNow, cancellationToken: cancellationToken);
}
}
```
### Interval-based job
An interval-based job is one that runs on a recurring loop configured as a fixed amount of time, not unlike how [reminders](https://docs.dapr.io/developing-applications/building-blocks/actors/actors-timers-reminders/#actor-reminders) work in the Actors building block today. These jobs can be scheduled with a number of optional arguments as well:
| Argument Name | Type | Description | Required |
|---|---|---|---|
| jobName | string | The name of the job being scheduled. | Yes |
| interval | TimeSpan | The interval at which the job should be triggered. | Yes |
| startingFrom | DateTime | The point in time from which the job schedule should start. | No |
| repeats | int | The maximum number of times the job should be triggered. | No |
| ttl | When the job should expires and no longer trigger. | No |
| payload | ReadOnlyMemory<byte> | Job data provided to the invocation endpoint when triggered. | No |
| cancellationToken | CancellationToken | Used to cancel out of the operation early, e.g. because of an operation timeout. | No |
Interval-based jobs can be scheduled from the Dapr Jobs client as in the following example:
```cs
public class MyOperation(DaprJobsClient daprJobsClient)
{
public async Task ScheduleIntervalJobAsync(CancellationToken cancellationToken)
{
var hourlyInterval = TimeSpan.FromHours(1);
//Trigger the job hourly, but a maximum of 5 times
await daprJobsClient.ScheduleIntervalJobAsync("myJobName", hourlyInterval, repeats: 5), cancellationToken: cancellationToken;
}
}
```
### Cron-based job
A Cron-based job is scheduled using a Cron expression. This gives more calendar-based control over when the job is triggered as it can used calendar-based values in the expression. Like the other options, these jobs can be scheduled with a number of optional arguments as well:
| Argument Name | Type | Description | Required |
|---|---|---|---|
| jobName | string | The name of the job being scheduled. | Yes |
| cronExpression | string | The systemd Cron-like expression indicating when the job should be triggered. | Yes |
| startingFrom | DateTime | The point in time from which the job schedule should start. | No |
| repeats | int | The maximum number of times the job should be triggered. | No |
| ttl | When the job should expires and no longer trigger. | No |
| payload | ReadOnlyMemory<byte> | Job data provided to the invocation endpoint when triggered. | No |
| cancellationToken | CancellationToken | Used to cancel out of the operation early, e.g. because of an operation timeout. | No |
A Cron-based job can be scheduled from the Dapr Jobs client as follows:
```cs
public class MyOperation(DaprJobsClient daprJobsClient)
{
public async Task ScheduleCronJobAsync(CancellationToken cancellationToken)
{
//At the top of every other hour on the fifth day of the month
const string cronSchedule = "0 */2 5 * *";
//Don't start this until next month
var now = DateTime.UtcNow;
var oneMonthFromNow = now.AddMonths(1);
var firstOfNextMonth = new DateTime(oneMonthFromNow.Year, oneMonthFromNow.Month, 1, 0, 0, 0);
//Trigger the job hourly, but a maximum of 5 times
await daprJobsClient.ScheduleCronJobAsync("myJobName", cronSchedule, dueTime: firstOfNextMonth, cancellationToken: cancellationToken);
}
}
```
## Get details of already-scheduled job
If you know the name of an already-scheduled job, you can retrieve its metadata without waiting for it to
be triggered. The returned `JobDetails` exposes a few helpful properties for consuming the information from the Dapr Jobs API:
- If the `Schedule` property contains a Cron expression, the `IsCronExpression` property will be true and the expression will also be available in the `CronExpression` property.
- If the `Schedule` property contains a duration value, the `IsIntervalExpression` property will instead be true and the value will be converted to a `TimeSpan` value accessible from the `Interval` property.
This can be done by using the following:
```cs
public class MyOperation(DaprJobsClient daprJobsClient)
{
public async Task<JobDetails> GetJobDetailsAsync(string jobName, CancellationToken cancellationToken)
{
var jobDetails = await daprJobsClient.GetJobAsync(jobName, canecllationToken);
return jobDetails;
}
}
```
## Delete a scheduled job
To delete a scheduled job, you'll need to know its name. From there, it's as simple as calling the `DeleteJobAsync` method on the Dapr Jobs client:
```cs
public class MyOperation(DaprJobsClient daprJobsClient)
{
public async Task DeleteJobAsync(string jobName, CancellationToken cancellationToken)
{
await daprJobsClient.DeleteJobAsync(jobName, cancellationToken);
}
}
```

View File

@ -0,0 +1,197 @@
---
type: docs
title: "DaprJobsClient usage"
linkTitle: "DaprJobsClient usage"
weight: 59000
description: Essential tips and advice for using DaprJobsClient
---
## Lifetime management
A `DaprJobsClient` is a version of the Dapr client that is dedicated to interacting with the Dapr Jobs API. It can be
registered alongside a `DaprClient` and other Dapr clients without issue.
It maintains access to networking resources in the form of TCP sockets used to communicate with the Dapr sidecar and
implements `IDisposable` to support the eager cleanup of resources.
For best performance, create a single long-lived instance of `DaprJobsClient` and provide access to that shared instance
throughout your application. `DaprJobsClient` instances are thread-safe and intended to be shared.
This can be aided by utilizing the dependency injection functionality. The registration method supports registration using
as a singleton, a scoped instance or as transient (meaning it's recreated every time it's injected), but also enables
registration to utilize values from an `IConfiguration` or other injected service in a way that's impractical when
creating the client from scratch in each of your classes.
Avoid creating a `DaprJobsClient` for each operation and disposing it when the operation is complete.
## Configuring DaprJobsClient via the DaprJobsClientBuilder
A `DaprJobsClient` can be configured by invoking methods on the `DaprJobsClientBuilder` class before calling `.Build()`
to create the client itself. The settings for each `DaprJobsClient` are separate
and cannot be changed after calling `.Build()`.
```cs
var daprJobsClient = new DaprJobsClientBuilder()
.UseDaprApiToken("abc123") // Specify the API token used to authenticate to other Dapr sidecars
.Build();
```
The `DaprJobsClientBuilder` contains settings for:
- The HTTP endpoint of the Dapr sidecar
- The gRPC endpoint of the Dapr sidecar
- The `JsonSerializerOptions` object used to configure JSON serialization
- The `GrpcChannelOptions` object used to configure gRPC
- The API token used to authenticate requests to the sidecar
- The factory method used to create the `HttpClient` instance used by the SDK
- The timeout used for the `HttpClient` instance when making requests to the sidecar
The SDK will read the following environment variables to configure the default values:
- `DAPR_HTTP_ENDPOINT`: used to find the HTTP endpoint of the Dapr sidecar, example: `https://dapr-api.mycompany.com`
- `DAPR_GRPC_ENDPOINT`: used to find the gRPC endpoint of the Dapr sidecar, example: `https://dapr-grpc-api.mycompany.com`
- `DAPR_HTTP_PORT`: if `DAPR_HTTP_ENDPOINT` is not set, this is used to find the HTTP local endpoint of the Dapr sidecar
- `DAPR_GRPC_PORT`: if `DAPR_GRPC_ENDPOINT` is not set, this is used to find the gRPC local endpoint of the Dapr sidecar
- `DAPR_API_TOKEN`: used to set the API token
### Configuring gRPC channel options
Dapr's use of `CancellationToken` for cancellation relies on the configuration of the gRPC channel options. If you need
to configure these options yourself, make sure to enable the [ThrowOperationCanceledOnCancellation setting](https://grpc.github.io/grpc/csharp-dotnet/api/Grpc.Net.Client.GrpcChannelOptions.html#Grpc_Net_Client_GrpcChannelOptions_ThrowOperationCanceledOnCancellation).
```cs
var daprJobsClient = new DaprJobsClientBuilder()
.UseGrpcChannelOptions(new GrpcChannelOptions { ... ThrowOperationCanceledOnCancellation = true })
.Build();
```
## Using cancellation with `DaprJobsClient`
The APIs on `DaprJobsClient` perform asynchronous operations and accept an optional `CancellationToken` parameter. This
follows a standard .NET practice for cancellable operations. Note that when cancellation occurs, there is no guarantee that
the remote endpoint stops processing the request, only that the client has stopped waiting for completion.
When an operation is cancelled, it will throw an `OperationCancelledException`.
## Configuring `DaprJobsClient` via dependency injection
Using the built-in extension methods for registering the `DaprJobsClient` in a dependency injection container can
provide the benefit of registering the long-lived service a single time, centralize complex configuration and improve
performance by ensuring similarly long-lived resources are re-purposed when possible (e.g. `HttpClient` instances).
There are three overloads available to give the developer the greatest flexibility in configuring the client for their
scenario. Each of these will register the `IHttpClientFactory` on your behalf if not already registered, and configure
the `DaprJobsClientBuilder` to use it when creating the `HttpClient` instance in order to re-use the same instance as
much as possible and avoid socket exhaustion and other issues.
In the first approach, there's no configuration done by the developer and the `DaprJobsClient` is configured with the
default settings.
```cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDaprJobsClient(); //Registers the `DaprJobsClient` to be injected as needed
var app = builder.Build();
```
Sometimes the developer will need to configure the created client using the various configuration options detailed
above. This is done through an overload that passes in the `DaprJobsClientBuiler` and exposes methods for configuring
the necessary options.
```cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDaprJobsClient((_, daprJobsClientBuilder) => {
//Set the API token
daprJobsClientBuilder.UseDaprApiToken("abc123");
//Specify a non-standard HTTP endpoint
daprJobsClientBuilder.UseHttpEndpoint("http://dapr.my-company.com");
});
var app = builder.Build();
```
Finally, it's possible that the developer may need to retrieve information from another service in order to populate
these configuration values. That value may be provided from a `DaprClient` instance, a vendor-specific SDK or some
local service, but as long as it's also registered in DI, it can be injected into this configuration operation via the
last overload:
```cs
var builder = WebApplication.CreateBuilder(args);
//Register a fictional service that retrieves secrets from somewhere
builder.Services.AddSingleton<SecretService>();
builder.Services.AddDaprJobsClient((serviceProvider, daprJobsClientBuilder) => {
//Retrieve an instance of the `SecretService` from the service provider
var secretService = serviceProvider.GetRequiredService<SecretService>();
var daprApiToken = secretService.GetSecret("DaprApiToken").Value;
//Configure the `DaprJobsClientBuilder`
daprJobsClientBuilder.UseDaprApiToken(daprApiToken);
});
var app = builder.Build();
```
## Understanding payload serialization on DaprJobsClient
While there are many methods on the `DaprClient` that automatically serialize and deserialize data using the
`System.Text.Json` serializer, this SDK takes a different philosophy. Instead, the relevant methods accept an optional
payload of `ReadOnlyMemory<byte>` meaning that serialization is an exercise left to the developer and is not
generally handled by the SDK.
That said, there are some helper extension methods available for each of the scheduling methods. If you know that you
want to use a type that's JSON-serializable, you can use the `Schedule*WithPayloadAsync` method for each scheduling
type that accepts an `object` as a payload and an optional `JsonSerializerOptions` to use when serializing the value.
This will convert the value to UTF-8 encoded bytes for you as a convenience. Here's an example of what this might
look like when scheduling a Cron expression:
```cs
public sealed record Doodad (string Name, int Value);
//...
var doodad = new Doodad("Thing", 100);
await daprJobsClient.ScheduleCronJobWithPayloadAsync("myJob", "5 * * * *", doodad);
```
In the same vein, if you have a plain string value, you can use an overload of the same method to serialize a
string-typed payload and the JSON serialization step will be skipped and it'll only be encoded to an array of
UTF-8 encoded bytes. Here's an example of what this might look like when scheduling a one-time job:
```cs
var now = DateTime.UtcNow;
var oneWeekFromNow = now.AddDays(7);
await daprJobsClient.ScheduleOneTimeJobWithPayloadAsync("myOtherJob", oneWeekFromNow, "This is a test!");
```
The delegate handling the job invocation expects at least two arguments to be present:
- A `string` that is populated with the `jobName`, providing the name of the invoked job
- A `ReadOnlyMemory<byte>` that is populated with the bytes originally provided during the job registration.
Because the payload is stored as a `ReadOnlyMemory<byte>`, the developer has the freedom to serialize and deserialize
as they wish, but there are again two helper extensions included that can deserialize this to either a JSON-compatible
type or a string. Both methods assume that the developer encoded the originally scheduled job (perhaps using the
helper serialization methods) as these methods will not force the bytes to represent something they're not.
To deserialize the bytes to a string, the following helper method can be used:
```cs
var payloadAsString = Encoding.UTF8.GetString(jobPayload.Span); //If successful, returns a string with the value
```
## Error handling
Methods on `DaprJobsClient` will throw a `DaprJobsServiceException` if an issue is encountered between the SDK
and the Jobs API service running on the Dapr sidecar. If a failure is encountered because of a poorly formatted
request made to the Jobs API service through this SDK, a `DaprMalformedJobException` will be thrown. In case of
illegal argument values, the appropriate standard exception will be thrown (e.g. `ArgumentOutOfRangeException`
or `ArgumentNullException`) with the name of the offending argument. And for anything else, a `DaprException`
will be thrown.
The most common cases of failure will be related to:
- Incorrect argument formatting while engaging with the Jobs API
- Transient failures such as a networking problem
- Invalid data, such as a failure to deserialize a value into a type it wasn't originally serialized from
In any of these cases, you can examine more exception details through the `.InnerException` property.

View File

@ -0,0 +1,17 @@
---
type: docs
title: "Dapr Messaging .NET SDK"
linkTitle: "Messaging"
weight: 60000
description: Get up and running with the Dapr Messaging .NET SDK
---
With the Dapr Messaging package, you can interact with the Dapr messaging APIs from a .NET application. In the
v1.15 release, this package only contains the functionality corresponding to the
[streaming PubSub capability](https://docs.dapr.io/developing-applications/building-blocks/pubsub/howto-publish-subscribe/#subscribe-to-topics).
Future Dapr .NET SDK releases will migrate existing messaging capabilities out from Dapr.Client to this
Dapr.Messaging package. This will be documented in the release notes, documentation and obsolete attributes in advance.
To get started, walk through the [Dapr Messaging]({{< ref dotnet-messaging-pubsub-howto.md >}}) how-to guide and
refer to [best practices documentation]({{< ref dotnet-messaging-pubsub-usage.md >}}) for additional guidance.

View File

@ -0,0 +1,268 @@
---
type: docs
title: "How to: Author and manage Dapr streaming subscriptions in the .NET SDK"
linkTitle: "How to: Author & manage streaming subscriptions"
weight: 61000
description: Learn how to author and manage Dapr streaming subscriptions using the .NET SDK
---
Let's create a subscription to a pub/sub topic or queue at using the streaming capability. We'll use the
[simple example provided here](https://github.com/dapr/dotnet-sdk/tree/master/examples/Client/PublishSubscribe/StreamingSubscriptionExample),
for the following demonstration and walk through it as an explainer of how you can configure message handlers at
runtime and which do not require an endpoint to be pre-configured. In this guide, you will:
- Deploy a .NET Web API application ([StreamingSubscriptionExample](https://github.com/dapr/dotnet-sdk/tree/master/examples/Client/PublishSubscribe/StreamingSubscriptionExample))
- Utilize the Dapr .NET Messaging SDK to subscribe dynamically to a pub/sub topic.
## Prerequisites
- [Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/)
- [Initialized Dapr environment](https://docs.dapr.io/getting-started/install-dapr-selfhost)
- [.NET 6](https://dotnet.microsoft.com/download/dotnet/6.0), [.NET 8](https://dotnet.microsoft.com/download/dotnet/8.0) or [.NET 9](https://dotnet.microsoft.com/download/dotnet/9.0) installed
- [Dapr.Messaging](https://www.nuget.org/packages/Dapr.Messaging) NuGet package installed to your project
{{% alert title="Note" color="primary" %}}
Note that while .NET 6 is the minimum support version of .NET in Dapr v1.15, only .NET 8 and .NET 9 will continue to be supported by Dapr in v1.16 and later.
{{% /alert %}}
## Set up the environment
Clone the [.NET SDK repo](https://github.com/dapr/dotnet-sdk).
```sh
git clone https://github.com/dapr/dotnet-sdk.git
```
From the .NET SDK root directory, navigate to the Dapr streaming PubSub example.
```sh
cd examples/Client/PublishSubscribe
```
## Run the application locally
To run the Dapr application, you need to start the .NET program and a Dapr sidecar. Navigate to the `StreamingSubscriptionExample` directory.
```sh
cd StreamingSubscriptionExample
```
We'll run a command that starts both the Dapr sidecar and the .NET program at the same time.
```sh
dapr run --app-id pubsubapp --dapr-grpc-port 4001 --dapr-http-port 3500 -- dotnet run
```
> Dapr listens for HTTP requests at `http://localhost:3500` and internal Jobs gRPC requests at `http://localhost:4001`.
## Register the Dapr PubSub client with dependency injection
The Dapr Messaging SDK provides an extension method to simplify the registration of the Dapr PubSub client. Before
completing the dependency injection registration in `Program.cs`, add the following line:
```csharp
var builder = WebApplication.CreateBuilder(args);
//Add anywhere between these two
builder.Services.AddDaprPubSubClient(); //That's it
var app = builder.Build();
```
It's possible that you may want to provide some configuration options to the Dapr PubSub client that
should be present with each call to the sidecar such as a Dapr API token, or you want to use a non-standard
HTTP or gRPC endpoint. This be possible through use of an overload of the registration method that allows configuration
of a `DaprPublishSubscribeClientBuilder` instance:
```csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDaprPubSubClient((_, daprPubSubClientBuilder) => {
daprPubSubClientBuilder.UseDaprApiToken("abc123");
daprPubSubClientBuilder.UseHttpEndpoint("http://localhost:8512"); //Non-standard sidecar HTTP endpoint
});
var app = builder.Build();
```
Still, it's possible that whatever values you wish to inject need to be retrieved from some other source, itself registered as a dependency. There's one more overload you can use to inject an `IServiceProvider` into the configuration action method. In the following example, we register a fictional singleton that can retrieve secrets from somewhere and pass it into the configuration method for `AddDaprJobClient` so
we can retrieve our Dapr API token from somewhere else for registration here:
```csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<SecretRetriever>();
builder.Services.AddDaprPubSubClient((serviceProvider, daprPubSubClientBuilder) => {
var secretRetriever = serviceProvider.GetRequiredService<SecretRetriever>();
var daprApiToken = secretRetriever.GetSecret("DaprApiToken").Value;
daprPubSubClientBuilder.UseDaprApiToken(daprApiToken);
daprPubSubClientBuilder.UseHttpEndpoint("http://localhost:8512");
});
var app = builder.Build();
```
## Use the Dapr PubSub client using IConfiguration
It's possible to configure the Dapr PubSub client using the values in your registered `IConfiguration` as well without
explicitly specifying each of the value overrides using the `DaprPublishSubscribeClientBuilder` as demonstrated in the previous
section. Rather, by populating an `IConfiguration` made available through dependency injection the `AddDaprPubSubClient()`
registration will automatically use these values over their respective defaults.
Start by populating the values in your configuration. This can be done in several different ways as demonstrated below.
### Configuration via `ConfigurationBuilder`
Application settings can be configured without using a configuration source and by instead populating the value in-memory
using a `ConfigurationBuilder` instance:
```csharp
var builder = WebApplication.CreateBuilder();
//Create the configuration
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string> {
{ "DAPR_HTTP_ENDPOINT", "http://localhost:54321" },
{ "DAPR_API_TOKEN", "abc123" }
})
.Build();
builder.Configuration.AddConfiguration(configuration);
builder.Services.AddDaprPubSubClient(); //This will automatically populate the HTTP endpoint and API token values from the IConfiguration
```
### Configuration via Environment Variables
Application settings can be accessed from environment variables available to your application.
The following environment variables will be used to populate both the HTTP endpoint and API token used to register the
Dapr PubSub client.
| Key | Value |
|--------------------|------------------------|
| DAPR_HTTP_ENDPOINT | http://localhost:54321 |
| DAPR_API_TOKEN | abc123 |
```csharp
var builder = WebApplication.CreateBuilder();
builder.Configuration.AddEnvironmentVariables();
builder.Services.AddDaprPubSubClient();
```
The Dapr PubSub client will be configured to use both the HTTP endpoint `http://localhost:54321` and populate all outbound
requests with the API token header `abc123`.
### Configuration via prefixed Environment Variables
However, in shared-host scenarios where there are multiple applications all running on the same machine without using
containers or in development environments, it's not uncommon to prefix environment variables. The following example
assumes that both the HTTP endpoint and the API token will be pulled from environment variables prefixed with the
value "myapp_". The two environment variables used in this scenario are as follows:
| Key | Value |
|--------------------------|------------------------|
| myapp_DAPR_HTTP_ENDPOINT | http://localhost:54321 |
| myapp_DAPR_API_TOKEN | abc123 |
These environment variables will be loaded into the registered configuration in the following example and made available
without the prefix attached.
```csharp
var builder = WebApplication.CreateBuilder();
builder.Configuration.AddEnvironmentVariables(prefix: "myapp_");
builder.Services.AddDaprPubSubClient();
```
The Dapr PubSub client will be configured to use both the HTTP endpoint `http://localhost:54321` and populate all outbound
requests with the API token header `abc123`.
## Use the Dapr PubSub client without relying on dependency injection
While the use of dependency injection simplifies the use of complex types in .NET and makes it easier to
deal with complicated configurations, you're not required to register the `DaprPublishSubscribeClient` in this way.
Rather, you can also elect to create an instance of it from a `DaprPublishSubscribeClientBuilder` instance as
demonstrated below:
```cs
public class MySampleClass
{
public void DoSomething()
{
var daprPubSubClientBuilder = new DaprPublishSubscribeClientBuilder();
var daprPubSubClient = daprPubSubClientBuilder.Build();
//Do something with the `daprPubSubClient`
}
}
```
## Set up message handler
The streaming subscription implementation in Dapr gives you greater control over handling backpressure from events by
leaving the messages in the Dapr runtime until your application is ready to accept them. The .NET SDK supports a
high-performance queue for maintaining a local cache of these messages in your application while processing is pending.
These messages will persist in the queue until processing either times out for each one or a response action is taken
for each (typically after processing succeeds or fails). Until this response action is received by the Dapr runtime,
the messages will be persisted by Dapr and made available in case of a service failure.
The various response actions available are as follows:
| Response Action | Description |
| --- | --- |
| Retry | The event should be delivered again in the future. |
| Drop | The event should be deleted (or forwarded to a dead letter queue, if configured) and not attempted again. |
| Success | The event should be deleted as it was successfully processed. |
The handler will receive only one message at a time and if a cancellation token is provided to the subscription,
this token will be provided during the handler invocation.
The handler must be configured to return a `Task<TopicResponseAction>` indicating one of these operations, even if from
a try/catch block. If an exception is not caught by your handler, the subscription will use the response action configured
in the options during subscription registration.
The following demonstrates the sample message handler provided in the example:
```csharp
Task<TopicResponseAction> HandleMessageAsync(TopicMessage message, CancellationToken cancellationToken = default)
{
try
{
//Do something with the message
Console.WriteLine(Encoding.UTF8.GetString(message.Data.Span));
return Task.FromResult(TopicResponseAction.Success);
}
catch
{
return Task.FromResult(TopicResponseAction.Retry);
}
}
```
## Configure and subscribe to the PubSub topic
Configuration of the streaming subscription requires the name of the PubSub component registered with Dapr, the name
of the topic or queue being subscribed to, the `DaprSubscriptionOptions` providing the configuration for the subscription,
the message handler and an optional cancellation token. The only required argument to the `DaprSubscriptionOptions` is
the default `MessageHandlingPolicy` which consists of a per-event timeout and the `TopicResponseAction` to take when
that timeout occurs.
Other options are as follows:
| Property Name | Description |
|-----------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
| Metadata | Additional subscription metadata |
| DeadLetterTopic | The optional name of the dead-letter topic to send dropped messages to. |
| MaximumQueuedMessages | By default, there is no maximum boundary enforced for the internal queue, but setting this |
| property would impose an upper limit. | |
| MaximumCleanupTimeout | When the subscription is disposed of or the token flags a cancellation request, this specifies |
| the maximum amount of time available to process the remaining messages in the internal queue. | |
Subscription is then configured as in the following example:
```csharp
var messagingClient = app.Services.GetRequiredService<DaprPublishSubscribeClient>();
var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(60)); //Override the default of 30 seconds
var options = new DaprSubscriptionOptions(new MessageHandlingPolicy(TimeSpan.FromSeconds(10), TopicResponseAction.Retry));
var subscription = await messagingClient.SubscribeAsync("pubsub", "mytopic", options, HandleMessageAsync, cancellationTokenSource.Token);
```
## Terminate and clean up subscription
When you've finished with your subscription and wish to stop receiving new events, simply await a call to
`DisposeAsync()` on your subscription instance. This will cause the client to unregister from additional events and
proceed to finish processing all the events still leftover in the backpressure queue, if any, before disposing of any
internal resources. This cleanup will be limited to the timeout interval provided in the `DaprSubscriptionOptions` when
the subscription was registered and by default, this is set to 30 seconds.

View File

@ -0,0 +1,130 @@
---
type: docs
title: "DaprPublishSubscribeClient usage"
linkTitle: "DaprPublishSubscribeClient usage"
weight: 69000
description: Essential tips and advice for using DaprPublishSubscribeClient
---
## Lifetime management
A `DaprPublishSubscribeClient` is a version of the Dapr client that is dedicated to interacting with the Dapr Messaging API.
It can be registered alongside a `DaprClient` and other Dapr clients without issue.
It maintains access to networking resources in the form of TCP sockets used to communicate with the Dapr sidecar and implements
`IAsyncDisposable` to support the eager cleanup of resources.
For best performance, create a single long-lived instance of `DaprPublishSubscribeClient` and provide access to that shared
instance throughout your application. `DaprPublishSubscribeClient` instances are thread-safe and intended to be shared.
This can be aided by utilizing the dependency injection functionality. The registration method supports registration using
as a singleton, a scoped instance or as transient (meaning it's recreated every time it's injected), but also enables
registration to utilize values from an `IConfiguration` or other injected service in a way that's impractical when
creating the client from scratch in each of your classes.
Avoid creating a `DaprPublishSubscribeClient` for each operation and disposing it when the operation is complete. It's
intended that the `DaprPublishSubscribeClient` should only be disposed when you no longer wish to receive events on the
subscription as disposing it will cancel the ongoing receipt of new events.
## Configuring DaprPublishSubscribeClient via the DaprPublishSubscribeClientBuilder
A `DaprPublishSubscribeClient` can be configured by invoking methods on the `DaprPublishSubscribeClientBuilder` class
before calling `.Build()` to create the client itself. The settings for each `DaprPublishSubscribeClient` are separate
and cannot be changed after calling `.Build()`.
```cs
var daprPubsubClient = new DaprPublishSubscribeClientBuilder()
.UseDaprApiToken("abc123") // Specify the API token used to authenticate to other Dapr sidecars
.Build();
```
The `DaprPublishSubscribeClientBuilder` contains settings for:
- The HTTP endpoint of the Dapr sidecar
- The gRPC endpoint of the Dapr sidecar
- The `JsonSerializerOptions` object used to configure JSON serialization
- The `GrpcChannelOptions` object used to configure gRPC
- The API token used to authenticate requests to the sidecar
- The factory method used to create the `HttpClient` instance used by the SDK
- The timeout used for the `HttpClient` instance when making requests to the sidecar
The SDK will read the following environment variables to configure the default values:
- `DAPR_HTTP_ENDPOINT`: used to find the HTTP endpoint of the Dapr sidecar, example: `https://dapr-api.mycompany.com`
- `DAPR_GRPC_ENDPOINT`: used to find the gRPC endpoint of the Dapr sidecar, example: `https://dapr-grpc-api.mycompany.com`
- `DAPR_HTTP_PORT`: if `DAPR_HTTP_ENDPOINT` is not set, this is used to find the HTTP local endpoint of the Dapr sidecar
- `DAPR_GRPC_PORT`: if `DAPR_GRPC_ENDPOINT` is not set, this is used to find the gRPC local endpoint of the Dapr sidecar
- `DAPR_API_TOKEN`: used to set the API token
### Configuring gRPC channel options
Dapr's use of `CancellationToken` for cancellation relies on the configuration of the gRPC channel options. If you
need to configure these options yourself, make sure to enable the [ThrowOperationCanceledOnCancellation setting](https://grpc.github.io/grpc/csharp-dotnet/api/Grpc.Net.Client.GrpcChannelOptions.html#Grpc_Net_Client_GrpcChannelOptions_ThrowOperationCanceledOnCancellation).
```cs
var daprPubsubClient = new DaprPublishSubscribeClientBuilder()
.UseGrpcChannelOptions(new GrpcChannelOptions { ... ThrowOperationCanceledOnCancellation = true })
.Build();
```
## Using cancellation with `DaprPublishSubscribeClient`
The APIs on `DaprPublishSubscribeClient` perform asynchronous operations and accept an optional `CancellationToken`
parameter. This follows a standard .NET practice for cancellable operations. Note that when cancellation occurs, there is
no guarantee that the remote endpoint stops processing the request, only that the client has stopped waiting for completion.
When an operation is cancelled, it will throw an `OperationCancelledException`.
## Configuring `DaprPublishSubscribeClient` via dependency injection
Using the built-in extension methods for registering the `DaprPublishSubscribeClient` in a dependency injection container
can provide the benefit of registering the long-lived service a single time, centralize complex configuration and improve
performance by ensuring similarly long-lived resources are re-purposed when possible (e.g. `HttpClient` instances).
There are three overloads available to give the developer the greatest flexibility in configuring the client for their
scenario. Each of these will register the `IHttpClientFactory` on your behalf if not already registered, and configure
the `DaprPublishSubscribeClientBuilder` to use it when creating the `HttpClient` instance in order to re-use the same
instance as much as possible and avoid socket exhaustion and other issues.
In the first approach, there's no configuration done by the developer and the `DaprPublishSubscribeClient` is configured with
the default settings.
```cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.DaprPublishSubscribeClient(); //Registers the `DaprPublishSubscribeClient` to be injected as needed
var app = builder.Build();
```
Sometimes the developer will need to configure the created client using the various configuration options detailed above. This is done through an overload that passes in the `DaprJobsClientBuiler` and exposes methods for configuring the necessary options.
```cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDaprJobsClient((_, daprPubSubClientBuilder) => {
//Set the API token
daprPubSubClientBuilder.UseDaprApiToken("abc123");
//Specify a non-standard HTTP endpoint
daprPubSubClientBuilder.UseHttpEndpoint("http://dapr.my-company.com");
});
var app = builder.Build();
```
Finally, it's possible that the developer may need to retrieve information from another service in order to populate these configuration values. That value may be provided from a `DaprClient` instance, a vendor-specific SDK or some local service, but as long as it's also registered in DI, it can be injected into this configuration operation via the last overload:
```cs
var builder = WebApplication.CreateBuilder(args);
//Register a fictional service that retrieves secrets from somewhere
builder.Services.AddSingleton<SecretService>();
builder.Services.AddDaprPublishSubscribeClient((serviceProvider, daprPubSubClientBuilder) => {
//Retrieve an instance of the `SecretService` from the service provider
var secretService = serviceProvider.GetRequiredService<SecretService>();
var daprApiToken = secretService.GetSecret("DaprApiToken").Value;
//Configure the `DaprPublishSubscribeClientBuilder`
daprPubSubClientBuilder.UseDaprApiToken(daprApiToken);
});
var app = builder.Build();
```

View File

@ -1,7 +0,0 @@
---
type: docs
title: "Create servers with the Dapr .NET SDK"
linkTitle: "Server"
weight: 30000
description: How to create Dapr .NET servers
---

View File

@ -1,9 +0,0 @@
---
type: docs
title: "Dapr .NET SDK integration with ASP.NET"
linkTitle: "ASP.NET"
weight: 100000
description: How to create Dapr .NET services and virtual actors with the ASP.NET extension
---
# TODO

View File

@ -2,6 +2,6 @@
type: docs
title: "How to troubleshoot and debug with the Dapr .NET SDK"
linkTitle: "Troubleshooting"
weight: 100000
weight: 120000
description: Tips, tricks, and guides for troubleshooting and debugging with the Dapr .NET SDKs
---

View File

@ -0,0 +1,8 @@
---
type: docs
title: "Dapr Workflow .NET SDK"
linkTitle: "Workflow"
weight: 40000
description: Get up and running with Dapr Workflow and the Dapr .NET SDK
---

View File

@ -0,0 +1,179 @@
---
type: docs
title: "How to: Author and manage Dapr Workflow in the .NET SDK"
linkTitle: "How to: Author & manage workflows"
weight: 100000
description: Learn how to author and manage Dapr Workflow using the .NET SDK
---
Let's create a Dapr workflow and invoke it using the console. In the [provided order processing workflow example](https://github.com/dapr/dotnet-sdk/tree/master/examples/Workflow), the console prompts provide directions on how to both purchase and restock items. In this guide, you will:
- Deploy a .NET console application ([WorkflowConsoleApp](https://github.com/dapr/dotnet-sdk/tree/master/examples/Workflow/WorkflowConsoleApp)).
- Utilize the .NET workflow SDK and API calls to start and query workflow instances.
In the .NET example project:
- The main [`Program.cs`](https://github.com/dapr/dotnet-sdk/blob/master/examples/Workflow/WorkflowConsoleApp/Program.cs) file contains the setup of the app, including the registration of the workflow and workflow activities.
- The workflow definition is found in the [`Workflows` directory](https://github.com/dapr/dotnet-sdk/tree/master/examples/Workflow/WorkflowConsoleApp/Workflows).
- The workflow activity definitions are found in the [`Activities` directory](https://github.com/dapr/dotnet-sdk/tree/master/examples/Workflow/WorkflowConsoleApp/Activities).
## Prerequisites
- [Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/)
- [Initialized Dapr environment](https://docs.dapr.io/getting-started/install-dapr-selfhost/)
- [.NET 7](https://dotnet.microsoft.com/download/dotnet/7.0), [.NET 8](https://dotnet.microsoft.com/download/dotnet/8.0) or [.NET 9](https://dotnet.microsoft.com/download/dotnet/9.0) installed
{{% alert title="Note" color="primary" %}}
Dapr.Workflows supports .NET 7 or newer in v1.15. However, following the release of Dapr v1.16, only
.NET 8 and .NET 9 will be supported.
{{% /alert %}}
## Set up the environment
Clone the [.NET SDK repo](https://github.com/dapr/dotnet-sdk).
```sh
git clone https://github.com/dapr/dotnet-sdk.git
```
From the .NET SDK root directory, navigate to the Dapr Workflow example.
```sh
cd examples/Workflow
```
## Run the application locally
To run the Dapr application, you need to start the .NET program and a Dapr sidecar. Navigate to the `WorkflowConsoleApp` directory.
```sh
cd WorkflowConsoleApp
```
Start the program.
```sh
dotnet run
```
In a new terminal, navigate again to the `WorkflowConsoleApp` directory and run the Dapr sidecar alongside the program.
```sh
dapr run --app-id wfapp --dapr-grpc-port 4001 --dapr-http-port 3500
```
> Dapr listens for HTTP requests at `http://localhost:3500` and internal workflow gRPC requests at `http://localhost:4001`.
## Start a workflow
To start a workflow, you have two options:
1. Follow the directions from the console prompts.
1. Use the workflow API and send a request to Dapr directly.
This guide focuses on the workflow API option.
{{% alert title="Note" color="primary" %}}
- You can find the commands below in the `WorkflowConsoleApp`/`demo.http` file.
- The body of the curl request is the purchase order information used as the input of the workflow.
- The "12345678" in the commands represents the unique identifier for the workflow and can be replaced with any identifier of your choosing.
{{% /alert %}}
Run the following command to start a workflow.
{{< tabs "Linux/MacOS" "Windows">}}
{{% codetab %}}
```bash
curl -i -X POST http://localhost:3500/v1.0/workflows/dapr/OrderProcessingWorkflow/start?instanceID=12345678 \
-H "Content-Type: application/json" \
-d '{"Name": "Paperclips", "TotalCost": 99.95, "Quantity": 1}'
```
{{% /codetab %}}
{{% codetab %}}
```powershell
curl -i -X POST http://localhost:3500/v1.0/workflows/dapr/OrderProcessingWorkflow/start?instanceID=12345678 `
-H "Content-Type: application/json" `
-d '{"Name": "Paperclips", "TotalCost": 99.95, "Quantity": 1}'
```
{{% /codetab %}}
{{< /tabs >}}
If successful, you should see a response like the following:
```json
{"instanceID":"12345678"}
```
Send an HTTP request to get the status of the workflow that was started:
```bash
curl -i -X GET http://localhost:3500/v1.0/workflows/dapr/12345678
```
The workflow is designed to take several seconds to complete. If the workflow hasn't completed when you issue the HTTP request, you'll see the following JSON response (formatted for readability) with workflow status as `RUNNING`:
```json
{
"instanceID": "12345678",
"workflowName": "OrderProcessingWorkflow",
"createdAt": "2023-05-10T00:42:03.911444105Z",
"lastUpdatedAt": "2023-05-10T00:42:06.142214153Z",
"runtimeStatus": "RUNNING",
"properties": {
"dapr.workflow.custom_status": "",
"dapr.workflow.input": "{\"Name\": \"Paperclips\", \"TotalCost\": 99.95, \"Quantity\": 1}"
}
}
```
Once the workflow has completed running, you should see the following output, indicating that it has reached the `COMPLETED` status:
```json
{
"instanceID": "12345678",
"workflowName": "OrderProcessingWorkflow",
"createdAt": "2023-05-10T00:42:03.911444105Z",
"lastUpdatedAt": "2023-05-10T00:42:18.527704176Z",
"runtimeStatus": "COMPLETED",
"properties": {
"dapr.workflow.custom_status": "",
"dapr.workflow.input": "{\"Name\": \"Paperclips\", \"TotalCost\": 99.95, \"Quantity\": 1}",
"dapr.workflow.output": "{\"Processed\":true}"
}
}
```
When the workflow has completed, the stdout of the workflow app should look like:
```log
info: WorkflowConsoleApp.Activities.NotifyActivity[0]
Received order 12345678 for Paperclips at $99.95
info: WorkflowConsoleApp.Activities.ReserveInventoryActivity[0]
Reserving inventory: 12345678, Paperclips, 1
info: WorkflowConsoleApp.Activities.ProcessPaymentActivity[0]
Processing payment: 12345678, 99.95, USD
info: WorkflowConsoleApp.Activities.NotifyActivity[0]
Order 12345678 processed successfully!
```
If you have Zipkin configured for Dapr locally on your machine, then you can view the workflow trace spans in the Zipkin web UI (typically at http://localhost:9411/zipkin/).
## Demo
Watch this video [demonstrating .NET Workflow](https://youtu.be/BxiKpEmchgQ?t=2557):
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/BxiKpEmchgQ?start=2557" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
## Next steps
- [Try the Dapr Workflow quickstart]({{< ref workflow-quickstart.md >}})
- [Learn more about Dapr Workflow]({{< ref workflow-overview.md >}})

View File

@ -0,0 +1,137 @@
---
type: docs
title: "DaprWorkflowClient usage"
linkTitle: "DaprWorkflowClient usage"
weight: 100000
description: Essential tips and advice for using DaprWorkflowClient
---
## Lifetime management
A `DaprWorkflowClient` holds access to networking resources in the form of TCP sockets used to communicate with the Dapr sidecar as well
as other types used in the management and operation of Workflows. `DaprWorkflowClient` implements `IAsyncDisposable` to support eager
cleanup of resources.
## Dependency Injection
The `AddDaprWorkflow()` method will register the Dapr workflow services with ASP.NET Core dependency injection. This method
requires an options delegate that defines each of the workflows and activities you wish to register and use in your application.
{{% alert title="Note" color="primary" %}}
This method will attempt to register a `DaprClient` instance, but this will only work if it hasn't already been registered with another
lifetime. For example, an earlier call to `AddDaprClient()` with a singleton lifetime will always use a singleton regardless of the
lifetime chose for the workflow client. The `DaprClient` instance will be used to communicate with the Dapr sidecar and if it's not
yet registered, the lifetime provided during the `AddDaprWorkflow()` registration will be used to register the `DaprWorkflowClient`
as well as its own dependencies.
{{% /alert %}}
### Singleton Registration
By default, the `AddDaprWorkflow` method will register the `DaprWorkflowClient` and associated services using a singleton lifetime. This means
that the services will be instantiated only a single time.
The following is an example of how registration of the `DaprWorkflowClient` as it would appear in a typical `Program.cs` file:
```csharp
builder.Services.AddDaprWorkflow(options => {
options.RegisterWorkflow<YourWorkflow>();
options.RegisterActivity<YourActivity>();
});
var app = builder.Build();
await app.RunAsync();
```
### Scoped Registration
While this may generally be acceptable in your use case, you may instead wish to override the lifetime specified. This is done by passing a `ServiceLifetime`
argument in `AddDaprWorkflow`. For example, you may wish to inject another scoped service into your ASP.NET Core processing pipeline
that needs context used by the `DaprClient` that wouldn't be available if the former service were registered as a singleton.
This is demonstrated in the following example:
```csharp
builder.Services.AddDaprWorkflow(options => {
options.RegisterWorkflow<YourWorkflow>();
options.RegisterActivity<YourActivity>();
}, ServiceLifecycle.Scoped);
var app = builder.Build();
await app.RunAsync();
```
### Transient Registration
Finally, Dapr services can also be registered using a transient lifetime meaning that they will be initialized every time they're injected. This
is demonstrated in the following example:
```csharp
builder.Services.AddDaprWorkflow(options => {
options.RegisterWorkflow<YourWorkflow>();
options.RegisterActivity<YourActivity>();
}, ServiceLifecycle.Transient);
var app = builder.Build();
await app.RunAsync();
```
## Injecting Services into Workflow Activities
Workflow activities support the same dependency injection that developers have come to expect of modern C# applications. Assuming a proper
registration at startup, any such type can be injected into the constructor of the workflow activity and available to utilize during
the execution of the workflow. This makes it simple to add logging via an injected `ILogger` or access to other Dapr
building blocks by injecting `DaprClient` or `DaprJobsClient`, for example.
```csharp
internal sealed class SquareNumberActivity : WorkflowActivity<int, int>
{
private readonly ILogger _logger;
public MyActivity(ILogger logger)
{
this._logger = logger;
}
public override Task<int> RunAsync(WorkflowActivityContext context, int input)
{
this._logger.LogInformation("Squaring the value {number}", input);
var result = input * input;
this._logger.LogInformation("Got a result of {squareResult}", result);
return Task.FromResult(result);
}
}
```
### Using ILogger in Workflow
Because workflows must be deterministic, it is not possible to inject arbitrary services into them. For example,
if you were able to inject a standard `ILogger` into a workflow and it needed to be replayed because of an error,
subsequent replay from the event source log would result in the log recording additional operations that didn't actually
take place a second or third time because their results were sourced from the log. This has the potential to introduce
a significant amount of confusion. Rather, a replay-safe logger is made available for use within workflows. It will only
log events the first time the workflow runs and will not log anything whenever the workflow is being replaced.
This logger can be retrieved from a method present on the `WorkflowContext` available on your workflow instance and
otherwise used precisely as you might otherwise use an `ILogger` instance.
An end-to-end sample demonstrating this can be seen in the
[.NET SDK repository](https://github.com/dapr/dotnet-sdk/blob/master/examples/Workflow/WorkflowConsoleApp/Workflows/OrderProcessingWorkflow.cs)
but a brief extraction of this sample is available below.
```csharp
public class OrderProcessingWorkflow : Workflow<OrderPayload, OrderResult>
{
public override async Task<OrderResult> RunAsync(WorkflowContext context, OrderPayload order)
{
string orderId = context.InstanceId;
var logger = context.CreateReplaySafeLogger<OrderProcessingWorkflow>(); //Use this method to access the logger instance
logger.LogInformation("Received order {orderId} for {quantity} {name} at ${totalCost}", orderId, order.Quantity, order.Name, order.TotalCost);
//...
}
}
```

69
docs/RELEASE.md Normal file
View File

@ -0,0 +1,69 @@
# Dapr .NET SDK Release Process
> This information is intended for SDK maintainers. SDK users can ignore this document.
## Publish a SDK Release Candidate (RC)
RC release versions canonically use the form `<version>-rc<iteration>` where `<version>` represents the overall release version (e.g. `1.0`) and `<iteration>` represents a specific iteration of RC release (e.g. `01`, `02`, ..., `0n`).
Assume we intend to release `<version>` (e.g. `1.0-rc01`) of the SDK.
1. Create a release branch (if not already done) from `master`
```bash
git checkout -b release-<version>
```
1. Push the release branch to the `dotnet-sdk` repo (i.e. typically `origin`)
```bash
git push origin v<version>
```
1. Create a tag on the release branch for the RC version
```bash
git tag v<version>-rc<iteration>
```
1. Push the tag to the `dotnet-sdk` repo (i.e. typically `origin`)
```bash
git push origin v<version>-rc<iteration>
```
> This final step will generate a build and automatically publish the resulting packages to NuGet.
## Publish a SDK Release
Official (i.e. supported) release versions canonically use the form `<version>` where `<version>` represents the overall release version (e.g. `1.0`).
1. Create a release branch (if not already done) from `master`
```bash
git checkout -b release-<version>
```
1. Push the release branch to the `dotnet-sdk` repo (i.e. typically `origin`)
```bash
git push origin v<version>
```
1. Create a tag on the release branch for the release
```bash
git tag v<version>
```
1. Push the tag to the `dotnet-sdk` repo (i.e. typically `origin`)
```bash
git push origin v<version>
```
> This final step will generate a build and automatically publish the resulting packages to NuGet.
## NuGet Package Publishing
Publishing to NuGet requires keys generated by a member of the Dapr organization. Such keys are added as a [GitHub Action secret](https://github.com/dapr/dotnet-sdk/settings/secrets/actions) with the name `NUGETORG_DAPR_API_KEY` These keys expire and therefore must be maintained and the GitHub Actions secret updated periodically.

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Dapr.AI\Dapr.AI.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,23 @@
using Dapr.AI.Conversation;
using Dapr.AI.Conversation.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDaprConversationClient();
var app = builder.Build();
var conversationClient = app.Services.GetRequiredService<DaprConversationClient>();
var response = await conversationClient.ConverseAsync("conversation",
new List<DaprConversationInput>
{
new DaprConversationInput(
"Please write a witty haiku about the Dapr distributed programming framework at dapr.io",
DaprConversationRole.Generic)
});
Console.WriteLine("Received the following from the LLM:");
foreach (var resp in response.Outputs)
{
Console.WriteLine($"\t{resp.Result}");
}

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6</TargetFramework>
</PropertyGroup>
<ItemGroup>

View File

@ -1,16 +1,26 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
using Dapr.Actors.Communication;
using IDemoActor;
namespace ActorClient
{
using System;
using System.Threading;
using System.Threading.Tasks;
using Dapr.Actors;
using Dapr.Actors.Client;
using Dapr.Actors.Communication;
using IDemoActorInterface;
/// <summary>
/// Actor Client class.
@ -35,10 +45,10 @@ namespace ActorClient
// Make strongly typed Actor calls with Remoting.
// DemoActor is the type registered with Dapr runtime in the service.
var proxy = ActorProxy.Create<IDemoActor>(actorId, "DemoActor");
var proxy = ActorProxy.Create<IDemoActor.IDemoActor>(actorId, "DemoActor");
Console.WriteLine("Making call using actor proxy to save data.");
await proxy.SaveData(data);
await proxy.SaveData(data, TimeSpan.FromMinutes(10));
Console.WriteLine("Making call using actor proxy to get data.");
var receivedData = await proxy.GetData();
Console.WriteLine($"Received data is {receivedData}.");
@ -60,7 +70,7 @@ namespace ActorClient
}
catch (ActorMethodInvocationException ex)
{
if (ex.InnerException is NotImplementedException)
if (ex.InnerException is ActorInvokeException invokeEx && invokeEx.ActualExceptionType is "System.NotImplementedException")
{
Console.WriteLine($"Got Correct Exception from actor method invocation.");
}
@ -75,7 +85,7 @@ namespace ActorClient
var nonRemotingProxy = ActorProxy.Create(actorId, "DemoActor");
await nonRemotingProxy.InvokeMethodAsync("TestNoArgumentNoReturnType");
await nonRemotingProxy.InvokeMethodAsync("SaveData", data);
var res = await nonRemotingProxy.InvokeMethodAsync<MyData>("GetData");
await nonRemotingProxy.InvokeMethodAsync<MyData>("GetData");
Console.WriteLine("Registering the timer and reminder");
await proxy.RegisterTimer();
@ -87,11 +97,41 @@ namespace ActorClient
receivedData = await proxy.GetData();
Console.WriteLine($"Received data is {receivedData}.");
Console.WriteLine("Getting details of the registered reminder");
var reminder = await proxy.GetReminder();
Console.WriteLine($"Received reminder is {reminder}.");
Console.WriteLine("Deregistering timer. Timers would any way stop if the actor is deactivated as part of Dapr garbage collection.");
await proxy.UnregisterTimer();
Console.WriteLine("Deregistering reminder. Reminders are durable and would not stop until an explicit deregistration or the actor is deleted.");
await proxy.UnregisterReminder();
Console.WriteLine("Registering reminder with repetitions - The reminder will repeat 3 times.");
await proxy.RegisterReminderWithRepetitions(3);
Console.WriteLine("Waiting so the reminder can be triggered");
await Task.Delay(5000);
Console.WriteLine("Getting details of the registered reminder");
reminder = await proxy.GetReminder();
Console.WriteLine($"Received reminder is {reminder?.ToString() ?? "None"} (expecting None).");
Console.WriteLine("Registering reminder with ttl and repetitions, i.e. reminder stops when either condition is met - The reminder will repeat 2 times.");
await proxy.RegisterReminderWithTtlAndRepetitions(TimeSpan.FromSeconds(5), 2);
Console.WriteLine("Getting details of the registered reminder");
reminder = await proxy.GetReminder();
Console.WriteLine($"Received reminder is {reminder}.");
Console.WriteLine("Deregistering reminder. Reminders are durable and would not stop until an explicit deregistration or the actor is deleted.");
await proxy.UnregisterReminder();
Console.WriteLine("Registering reminder and Timer with TTL - The reminder will self delete after 10 seconds.");
await proxy.RegisterReminderWithTtl(TimeSpan.FromSeconds(10));
await proxy.RegisterTimerWithTtl(TimeSpan.FromSeconds(10));
Console.WriteLine("Getting details of the registered reminder");
reminder = await proxy.GetReminder();
Console.WriteLine($"Received reminder is {reminder}.");
// Track the reminder.
var timer = new Timer(async state => Console.WriteLine($"Received data: {await proxy.GetData()}"), null, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5));
await Task.Delay(TimeSpan.FromSeconds(21));
await timer.DisposeAsync();
Console.WriteLine("Creating a Bank Actor");
var bank = ActorProxy.Create<IBankActor>(ActorId.CreateRandom(), "DemoActor");

View File

@ -1,11 +1,19 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
//
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
using IDemoActorInterface;
using IDemoActor;
namespace DaprDemoActor
namespace DemoActor
{
public class BankService
{

View File

@ -1,16 +1,24 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
namespace DaprDemoActor
using System;
using System.Text.Json;
using System.Threading.Tasks;
using Dapr.Actors.Runtime;
using IDemoActor;
namespace DemoActor
{
using System;
using System.Text.Json;
using System.Threading.Tasks;
using Dapr.Actors.Runtime;
using IDemoActorInterface;
// The following example showcases a few features of Actors
//
// Every actor should inherit from the Actor type, and must implement one or more actor interfaces.
@ -19,7 +27,7 @@ namespace DaprDemoActor
// For Actors to use Reminders, it must derive from IRemindable.
// If you don't intend to use Reminder feature, you can skip implementing IRemindable and reminder
// specific methods which are shown in the code below.
public class DemoActor : Actor, IDemoActor, IBankActor, IRemindable
public class DemoActor : Actor, IDemoActor.IDemoActor, IBankActor, IRemindable
{
private const string StateName = "my_data";
@ -33,12 +41,12 @@ namespace DaprDemoActor
this.bank = bank;
}
public async Task SaveData(MyData data)
public async Task SaveData(MyData data, TimeSpan ttl)
{
Console.WriteLine($"This is Actor id {this.Id} with data {data}.");
// Set State using StateManager, state is saved after the method execution.
await this.StateManager.SetStateAsync<MyData>(StateName, data);
await this.StateManager.SetStateAsync<MyData>(StateName, data, ttl);
}
public Task<MyData> GetData()
@ -62,6 +70,35 @@ namespace DaprDemoActor
await this.RegisterReminderAsync("TestReminder", null, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5));
}
public async Task RegisterReminderWithTtl(TimeSpan ttl)
{
await this.RegisterReminderAsync("TestReminder", null, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5), ttl);
}
public async Task RegisterReminderWithRepetitions(int repetitions)
{
await this.RegisterReminderAsync("TestReminder", null, TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(1), repetitions);
}
public async Task RegisterReminderWithTtlAndRepetitions(TimeSpan ttl, int repetitions)
{
await this.RegisterReminderAsync("TestReminder", null, TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(1), repetitions, ttl);
}
public async Task<ActorReminderData> GetReminder()
{
var reminder = await this.GetReminderAsync("TestReminder");
return reminder is not null
? new ActorReminderData
{
Name = reminder.Name,
Period = reminder.Period,
DueTime = reminder.DueTime
}
: null;
}
public Task UnregisterReminder()
{
return this.UnregisterReminderAsync("TestReminder");
@ -72,7 +109,7 @@ namespace DaprDemoActor
// This method is invoked when an actor reminder is fired.
var actorState = await this.StateManager.GetStateAsync<MyData>(StateName);
actorState.PropertyB = $"Reminder triggered at '{DateTime.Now:yyyy-MM-ddTHH:mm:ss}'";
await this.StateManager.SetStateAsync<MyData>(StateName, actorState);
await this.StateManager.SetStateAsync<MyData>(StateName, actorState, ttl: TimeSpan.FromMinutes(5));
}
class TimerParams
@ -94,6 +131,18 @@ namespace DaprDemoActor
return this.RegisterTimerAsync("TestTimer", nameof(this.TimerCallback), serializedTimerParams, TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(3));
}
public Task RegisterTimerWithTtl(TimeSpan ttl)
{
var timerParams = new TimerParams
{
IntParam = 100,
StringParam = "timer test",
};
var serializedTimerParams = JsonSerializer.SerializeToUtf8Bytes(timerParams);
return this.RegisterTimerAsync("TestTimer", nameof(this.TimerCallback), serializedTimerParams, TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(3), ttl);
}
public Task UnregisterTimer()
{
return this.UnregisterTimerAsync("TestTimer");
@ -124,7 +173,7 @@ namespace DaprDemoActor
{
var state = await this.StateManager.GetStateAsync<MyData>(StateName);
state.PropertyA = $"Timer triggered at '{DateTime.Now:yyyyy-MM-ddTHH:mm:s}'";
await this.StateManager.SetStateAsync<MyData>(StateName, state);
await this.StateManager.SetStateAsync<MyData>(StateName, state, ttl: TimeSpan.FromMinutes(5));
var timerParams = JsonSerializer.Deserialize<TimerParams>(data);
Console.WriteLine("Timer parameter1: " + timerParams.IntParam);
Console.WriteLine("Timer parameter2: " + timerParams.StringParam);

View File

@ -1,13 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net6</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Dapr.Actors.AspNetCore\Dapr.Actors.AspNetCore.csproj" />
<ProjectReference Include="..\..\..\src\Dapr.Actors\Dapr.Actors.csproj" />
<ProjectReference Include="..\IDemoActor\IDemoActor.csproj" />
</ItemGroup>
<PropertyGroup>
<IsPublishable>true</IsPublishable>
<EnableSdkContainerSupport>true</EnableSdkContainerSupport>
<ContainerRepository>demo-actor</ContainerRepository>
</PropertyGroup>
<ItemGroup>
<ContainerEnvironmentVariable Include="ASPNETCORE_URLS" Value="http://+:8080" />
<ContainerPort Include="8080" Type="tcp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Dapr.Actors.AspNetCore\Dapr.Actors.AspNetCore.csproj" />
<ProjectReference Include="..\..\..\src\Dapr.Actors\Dapr.Actors.csproj" />
<ProjectReference Include="..\IDemoActor\IDemoActor.csproj" />
</ItemGroup>
</Project>

View File

@ -1,13 +1,21 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
namespace DaprDemoActor
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
namespace DemoActor
{
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
public class Program
{
public static void Main(string[] args)

View File

@ -3,7 +3,7 @@
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:52190/",
"applicationUrl": "http://127.0.0.1:5010/",
"sslPort": 0
}
},
@ -21,7 +21,7 @@
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:5000/"
"applicationUrl": "http://localhost:5010/"
}
}
}
}

View File

@ -1,16 +1,24 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
namespace DaprDemoActor
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace DemoActor
{
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
public class Startup
{
public Startup(IConfiguration configuration)

View File

@ -0,0 +1,10 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}

View File

@ -0,0 +1,67 @@
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.in-memory
version: v1
metadata:
- name: actorStateStore
value: "true"
---
kind: Service
apiVersion: v1
metadata:
name: demoactor
labels:
app: demoactor
spec:
selector:
app: demoactor
ports:
- name: app-port
protocol: TCP
port: 5010
targetPort: app-port
- name: dapr-http
protocol: TCP
port: 3500
targetPort: 3500
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: demoactor
labels:
app: demoactor
spec:
replicas: 1
selector:
matchLabels:
app: demoactor
template:
metadata:
labels:
app: demoactor
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "demoactor"
dapr.io/app-port: "5010"
dapr.io/enable-api-logging: "true"
dapr.io/sidecar-listen-addresses: "0.0.0.0"
spec:
containers:
- name: demoactor
# image: <your-docker-registry>/demo-actor:latest
image: demo-actor:latest
# if you are using docker desktop, you can use imagePullPolicy: Never to use local image
imagePullPolicy: Never
env:
- name: APP_PORT
value: "5010"
- name: ASPNETCORE_URLS
value: "http://+:5010"
ports:
- name: app-port
containerPort: 5010

View File

@ -1,14 +1,22 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
namespace IDemoActorInterface
using System;
using System.Threading.Tasks;
using Dapr.Actors;
namespace IDemoActor
{
using System;
using System.Threading.Tasks;
using Dapr.Actors;
public interface IBankActor : IActor
{
Task<AccountBalance> GetAccountBalance();

View File

@ -1,13 +1,22 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
namespace IDemoActorInterface
using System;
using System.Threading.Tasks;
using Dapr.Actors;
namespace IDemoActor
{
using System.Threading.Tasks;
using Dapr.Actors;
/// <summary>
/// Interface for Actor method.
/// </summary>
@ -17,8 +26,9 @@ namespace IDemoActorInterface
/// Method to save data.
/// </summary>
/// <param name="data">DAta to save.</param>
/// <param name="ttl">TTL of state key.</param>
/// <returns>A task that represents the asynchronous save operation.</returns>
Task SaveData(MyData data);
Task SaveData(MyData data, TimeSpan ttl);
/// <summary>
/// Method to get data.
@ -44,6 +54,13 @@ namespace IDemoActorInterface
/// <returns>A task that represents the asynchronous save operation.</returns>
Task RegisterReminder();
/// <summary>
/// Registers a reminder.
/// </summary>
/// <param name="ttl">TimeSpan that dictates when the reminder expires.</param>
/// <returns>A task that represents the asynchronous save operation.</returns>
Task RegisterReminderWithTtl(TimeSpan ttl);
/// <summary>
/// Unregisters the registered reminder.
/// </summary>
@ -56,6 +73,35 @@ namespace IDemoActorInterface
/// <returns>A task that represents the asynchronous save operation.</returns>
Task RegisterTimer();
/// <summary>
/// Registers a timer.
/// </summary>
/// <param name="ttl">Optional TimeSpan that dictates when the timer expires.</param>
/// <returns>A task that represents the asynchronous save operation.</returns>
Task RegisterTimerWithTtl(TimeSpan ttl);
/// <summary>
/// Registers a reminder with repetitions.
/// </summary>
/// <param name="repetitions">The number of repetitions for which the reminder should be invoked.</param>
/// <returns>A task that represents the asynchronous save operation.</returns>
Task RegisterReminderWithRepetitions(int repetitions);
/// <summary>
/// Registers a reminder with ttl and repetitions.
/// </summary>
/// <param name="ttl">TimeSpan that dictates when the timer expires.</param>
/// <param name="repetitions">The number of repetitions for which the reminder should be invoked.</param>
/// <returns>A task that represents the asynchronous save operation.</returns>
Task RegisterReminderWithTtlAndRepetitions(TimeSpan ttl, int repetitions);
/// <summary>
/// Gets the registered reminder.
/// </summary>
/// <param name="reminderName">The name of the reminder.</param>
/// <returns>A task that returns the reminder after completion.</returns>
Task<ActorReminderData> GetReminder();
/// <summary>
/// Unregisters the registered timer.
/// </summary>
@ -86,4 +132,18 @@ namespace IDemoActorInterface
return $"PropertyA: {propAValue}, PropertyB: {propBValue}";
}
}
public class ActorReminderData
{
public string Name { get; set; }
public TimeSpan DueTime { get; set; }
public TimeSpan Period { get; set; }
public override string ToString()
{
return $"Name: {this.Name}, DueTime: {this.DueTime}, Period: {this.Period}";
}
}
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6</TargetFramework>
</PropertyGroup>
<ItemGroup>

View File

@ -4,7 +4,7 @@ The Actor example shows how to create a virtual actor (`DemoActor`) and invoke i
## Prerequisites
- [.NET Core 3.1 or .NET 5+](https://dotnet.microsoft.com/download) installed
- [.NET 6+](https://dotnet.microsoft.com/download) installed
- [Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/)
- [Initialized Dapr environment](https://docs.dapr.io/getting-started/install-dapr-selfhost/)
- [Dapr .NET SDK](https://github.com/dapr/dotnet-sdk/)
@ -22,12 +22,10 @@ The Actor example shows how to create a virtual actor (`DemoActor`) and invoke i
To run the actor service locally run this command in `DemoActor` directory:
```sh
dapr run --dapr-http-port 3500 --app-id demo_actor --app-port 5000 dotnet run
dapr run --dapr-http-port 3500 --app-id demo_actor --app-port 5010 dotnet run
```
The `DemoActor` service will listen on port `5000` for HTTP.
*Note: For Running the sample with ISS express, change the launchsettings.json to use 127.0.0.1 instead of localhost.*
The `DemoActor` service will listen on port `5010` for HTTP.
### Make client calls
@ -82,3 +80,80 @@ On Windows:
```sh
curl -X POST http://127.0.0.1:3500/v1.0/actors/DemoActor/abc/method/GetData
```
### Build and push Docker image
You can build the docker image of `DemoActor` service by running the following commands in the `DemoActor` project directory:
``` Bash
dotnet publish --os linux --arch x64 /t:PublishContainer -p ContainerImageTags='"latest"' --self-contained
```
The build produce and image with tag `demo-actor:latest` and load it in the local registry.
Now the image can be pushed to your remote Docker registry by running the following commands:
``` Bash
# Replace <your-docker-registry> with your Docker registry
docker tag demo-actor:latest <your-docker-registry>/demo-actor:latest
# Push the image to your Docker registry
docker push <your-docker-registry>/demo-actor:latest
```
### Deploy the Actor service to Kubernetes
#### Prerequisites
- A Kubernetes cluster with `kubectl` configured to access it.
- Dapr v1.14+ installed on the Kubernetes cluster. Follow the instructions [here](https://docs.dapr.io/getting-started/install-dapr-kubernetes/).
- A Docker registry where you pushed the `DemoActor` image.
#### Deploy the Actor service
For quick deployment you can install dapr in dev mode using the following command:
``` Bash
dapr init -k --dev
```
To deploy the `DemoActor` service to Kubernetes, you can use the provided Kubernetes manifest file `demo-actor.yaml` in the `DemoActor` project directory.
Before applying the manifest file, replace the image name in the manifest file with the image name you pushed to your Docker registry.
Part to update in `demo-actor.yaml`:
``` YAML
image: <your-docker-registry>/demoactor:latest
```
To install the application in `default` namespace, run the following command:
``` Bash
kubectl apply -f demo-actor.yaml
```
This will deploy the `DemoActor` service to Kubernetes. You can check the status of the deployment by running:
``` Bash
kubectl get pods -n default --watch
```
The manifest create 2 services:
- `demoactor` service: The service that hosts the `DemoActor` actor.
- `demoactor-dapr` service: The service that hosts the Dapr sidecar for the `DemoActor` actor.
### Make client calls to the deployed Actor service
To make client calls to the deployed `DemoActor` service, you can use the `ActorClient` project.
Before running the client, update the `DAPR_HTTP_PORT` environment variable in the `ActorClient` project directory to the port on which Dapr is running in the Kubernetes cluster.
On Linux, MacOS:
``` Bash
export DAPR_HTTP_PORT=3500
```
Than port-forward the `DemoActor` service to your local machine:
``` Bash
kubectl port-forward svc/demoactor 3500:3500
```
Now you can run the client project from the `ActorClient` directory:
``` Bash
dotnet run
```

View File

@ -1,7 +1,15 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
namespace ControllerSample
{

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6</TargetFramework>
</PropertyGroup>
<ItemGroup>

View File

@ -1,13 +1,27 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
using System.Linq;
namespace ControllerSample.Controllers
{
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Dapr;
using Dapr.AspNetCore;
using Dapr.Client;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
@ -31,6 +45,7 @@ namespace ControllerSample.Controllers
/// State store name.
/// </summary>
public const string StoreName = "statestore";
private readonly ILogger<SampleController> logger;
/// <summary>
@ -56,18 +71,94 @@ namespace ControllerSample.Controllers
/// <param name="daprClient">State client to interact with Dapr runtime.</param>
/// <returns>A <see cref="Task{TResult}"/> representing the result of the asynchronous operation.</returns>
/// "pubsub", the first parameter into the Topic attribute, is name of the default pub/sub configured by the Dapr CLI.
[Topic("pubsub", "deposit")]
[Topic("pubsub", "deposit", "amountDeadLetterTopic", false)]
[HttpPost("deposit")]
public async Task<ActionResult<Account>> Deposit(Transaction transaction, [FromServices] DaprClient daprClient)
{
logger.LogDebug("Enter deposit");
// Example reading cloudevent properties from the headers
var headerEntries = Request.Headers.Aggregate("", (current, header) => current + ($"------- Header: {header.Key} : {header.Value}" + Environment.NewLine));
logger.LogInformation(headerEntries);
logger.LogInformation("Enter deposit");
var state = await daprClient.GetStateEntryAsync<Account>(StoreName, transaction.Id);
state.Value ??= new Account() { Id = transaction.Id, };
logger.LogInformation("Id is {0}, the amount to be deposited is {1}", transaction.Id, transaction.Amount);
if (transaction.Amount < 0m)
{
return BadRequest(new { statusCode = 400, message = "bad request" });
}
state.Value.Balance += transaction.Amount;
logger.LogInformation("Balance for Id {0} is {1}", state.Value.Id, state.Value.Balance);
await state.SaveAsync();
return state.Value;
}
/// <summary>
/// Method for depositing multiple times to the account as specified in transaction.
/// </summary>
/// <param name="bulkMessage">List of entries of type BulkMessageModel received from dapr.</param>
/// <param name="daprClient">State client to interact with Dapr runtime.</param>
/// <returns>A <see cref="Task{TResult}"/> representing the result of the asynchronous operation.</returns>
/// "pubsub", the first parameter into the Topic attribute, is name of the default pub/sub configured by the Dapr CLI.
[Topic("pubsub", "multideposit", "amountDeadLetterTopic", false)]
[BulkSubscribe("multideposit", 500, 2000)]
[HttpPost("multideposit")]
public async Task<ActionResult<BulkSubscribeAppResponse>> MultiDeposit([FromBody]
BulkSubscribeMessage<BulkMessageModel<Transaction>>
bulkMessage, [FromServices] DaprClient daprClient)
{
logger.LogInformation("Enter bulk deposit");
List<BulkSubscribeAppResponseEntry> entries = new List<BulkSubscribeAppResponseEntry>();
foreach (var entry in bulkMessage.Entries)
{
try
{
var transaction = entry.Event.Data;
var state = await daprClient.GetStateEntryAsync<Account>(StoreName, transaction.Id);
state.Value ??= new Account() { Id = transaction.Id, };
logger.LogInformation("Id is {0}, the amount to be deposited is {1}",
transaction.Id, transaction.Amount);
if (transaction.Amount < 0m)
{
return BadRequest(new { statusCode = 400, message = "bad request" });
}
state.Value.Balance += transaction.Amount;
logger.LogInformation("Balance is {0}", state.Value.Balance);
await state.SaveAsync();
entries.Add(
new BulkSubscribeAppResponseEntry(entry.EntryId, BulkSubscribeAppResponseStatus.SUCCESS));
}
catch (Exception e)
{
logger.LogError(e.Message);
entries.Add(new BulkSubscribeAppResponseEntry(entry.EntryId, BulkSubscribeAppResponseStatus.RETRY));
}
}
return new BulkSubscribeAppResponse(entries);
}
/// <summary>
/// Method for viewing the error message when the deposit/withdrawal amounts
/// are negative.
/// </summary>
/// <param name="transaction">Transaction info.</param>
[Topic("pubsub", "amountDeadLetterTopic")]
[HttpPost("deadLetterTopicRoute")]
public ActionResult<Account> ViewErrorMessage(Transaction transaction)
{
logger.LogInformation("The amount cannot be negative: {0}", transaction.Amount);
return Ok();
}
/// <summary>
/// Method for withdrawing from account as specified in transaction.
/// </summary>
@ -75,19 +166,26 @@ namespace ControllerSample.Controllers
/// <param name="daprClient">State client to interact with Dapr runtime.</param>
/// <returns>A <see cref="Task{TResult}"/> representing the result of the asynchronous operation.</returns>
/// "pubsub", the first parameter into the Topic attribute, is name of the default pub/sub configured by the Dapr CLI.
[Topic("pubsub", "withdraw")]
[Topic("pubsub", "withdraw", "amountDeadLetterTopic", false)]
[HttpPost("withdraw")]
public async Task<ActionResult<Account>> Withdraw(Transaction transaction, [FromServices] DaprClient daprClient)
{
logger.LogDebug("Enter withdraw");
logger.LogInformation("Enter withdraw method...");
var state = await daprClient.GetStateEntryAsync<Account>(StoreName, transaction.Id);
logger.LogInformation("Id is {0}, the amount to be withdrawn is {1}", transaction.Id, transaction.Amount);
if (state.Value == null)
{
return this.NotFound();
}
if (transaction.Amount < 0m)
{
return BadRequest(new { statusCode = 400, message = "bad request" });
}
state.Value.Balance -= transaction.Amount;
logger.LogInformation("Balance is {0}", state.Value.Balance);
await state.SaveAsync();
return state.Value;
}
@ -101,9 +199,10 @@ namespace ControllerSample.Controllers
/// "pubsub", the first parameter into the Topic attribute, is name of the default pub/sub configured by the Dapr CLI.
[Topic("pubsub", "withdraw", "event.type ==\"withdraw.v2\"", 1)]
[HttpPost("withdraw.v2")]
public async Task<ActionResult<Account>> WithdrawV2(TransactionV2 transaction, [FromServices] DaprClient daprClient)
public async Task<ActionResult<Account>> WithdrawV2(TransactionV2 transaction,
[FromServices] DaprClient daprClient)
{
logger.LogDebug("Enter withdraw.v2");
logger.LogInformation("Enter withdraw.v2");
if (transaction.Channel == "mobile" && transaction.Amount > 10000)
{
return this.Unauthorized("mobile transactions for large amounts are not permitted.");
@ -122,11 +221,46 @@ namespace ControllerSample.Controllers
}
/// <summary>
/// Method for returning a BadRequest result which will cause Dapr sidecar to throw an RpcException
[HttpPost("throwException")]
public async Task<ActionResult<Account>> ThrowException(Transaction transaction, [FromServices] DaprClient daprClient)
/// Method for depositing to account as specified in transaction via a raw message.
/// </summary>
/// <param name="transaction">Transaction info.</param>
/// <param name="daprClient">State client to interact with Dapr runtime.</param>
/// <returns>A <see cref="Task{TResult}"/> representing the result of the asynchronous operation.</returns>
/// "pubsub", the first parameter into the Topic attribute, is name of the default pub/sub configured by the Dapr CLI.
[Topic("pubsub", "rawDeposit", true)]
[HttpPost("rawDeposit")]
public async Task<ActionResult<Account>> RawDeposit([FromBody] JsonDocument rawTransaction,
[FromServices] DaprClient daprClient)
{
Console.WriteLine("Enter ThrowException");
var transactionString = rawTransaction.RootElement.GetProperty("data_base64").GetString();
logger.LogInformation(
$"Enter deposit: {transactionString} - {Encoding.UTF8.GetString(Convert.FromBase64String(transactionString))}");
var transactionJson = JsonSerializer.Deserialize<JsonDocument>(Convert.FromBase64String(transactionString));
var transaction =
JsonSerializer.Deserialize<Transaction>(transactionJson.RootElement.GetProperty("data").GetRawText());
var state = await daprClient.GetStateEntryAsync<Account>(StoreName, transaction.Id);
state.Value ??= new Account() { Id = transaction.Id, };
logger.LogInformation("Id is {0}, the amount to be deposited is {1}", transaction.Id, transaction.Amount);
if (transaction.Amount < 0m)
{
return BadRequest(new { statusCode = 400, message = "bad request" });
}
state.Value.Balance += transaction.Amount;
logger.LogInformation("Balance is {0}", state.Value.Balance);
await state.SaveAsync();
return state.Value;
}
/// <summary>
/// Method for returning a BadRequest result which will cause Dapr sidecar to throw an RpcException
/// </summary>
[HttpPost("throwException")]
public async Task<ActionResult<Account>> ThrowException(Transaction transaction,
[FromServices] DaprClient daprClient)
{
logger.LogInformation("Enter ThrowException");
var task = Task.Delay(10);
await task;
return BadRequest(new { statusCode = 400, message = "bad request" });
@ -147,5 +281,18 @@ namespace ControllerSample.Controllers
{
return Ok();
}
/// <summary>
/// Method which uses <see cref="TopicMetadataAttribute" /> for binding this endpoint to a subscription and adds routingkey metadata.
/// </summary>
/// <param name="transaction"></param>
/// <returns></returns>
[Topic("pubsub", "topicmetadata")]
[TopicMetadata("routingKey", "keyA")]
[HttpPost("examplecustomtopicmetadata")]
public ActionResult<Account> ExampleCustomTopicMetadata(Transaction transaction)
{
return Ok();
}
}
}

View File

@ -1,7 +1,17 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
using Dapr.AspNetCore;
namespace ControllerSample
{

View File

@ -1,7 +1,15 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
namespace ControllerSample
{

View File

@ -1,12 +1,4 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:52195/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
@ -19,7 +11,6 @@
},
"ControllerSample": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"CUSTOM_PUBSUB": "custom-pubsub",
@ -27,5 +18,13 @@
},
"applicationUrl": "http://localhost:5000/"
}
},
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:54197/",
"sslPort": 44385
}
}
}

View File

@ -5,13 +5,14 @@ This sample shows using Dapr with ASP.NET Core controllers. This application is
It exposes the following endpoints over HTTP:
- GET `/{account}`: Get the balance for the account specified by `id`
- POST `/deposit`: Accepts a JSON payload to deposit money to an account
- POST `/multideposit`: Accepts a JSON payload to deposit money multiple times to a bulk subscribed topic
- POST `/withdraw`: Accepts a JSON payload to withdraw money from an account
The application also registers for pub/sub with the `deposit` and `withdraw` topics.
The application also registers for pub/sub with the `deposit`, `multideposit` and `withdraw` topics.
## Prerequisitess
- [.NET Core 3.1 or .NET 5+](https://dotnet.microsoft.com/download) installed
- [.NET 6+](https://dotnet.microsoft.com/download) installed
- [Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/)
- [Initialized Dapr environment](https://docs.dapr.io/getting-started/install-dapr-selfhost/)
- [Dapr .NET SDK](https://docs.dapr.io/developing-applications/sdks/dotnet/)
@ -25,8 +26,6 @@ The application also registers for pub/sub with the `deposit` and `withdraw` top
The application will listen on port 5000 for HTTP.
*Note: For Running the sample in ISS express, change the launchsettings.json to use 127.0.0.1 instead of localhost.*
### Examples
**Deposit Money**
@ -59,7 +58,76 @@ Output:
```
---
**Deposit Money multiple times to a bulk subscribed topic**
On Linux, MacOS:
```
curl -X POST http://127.0.0.1:5000/multideposit \
-H 'Content-Type: application/json' \
-d '{
"entries":[
{
"entryId":"653dd9f5-f375-499b-8b2a-c4599bbd36b0",
"event":{
"data":{
"amount":10,
"id":"17"
},
"datacontenttype":"application/json",
"id":"DaprClient",
"pubsubname":"pubsub",
"source":"Dapr",
"specversion":"1.0",
"topic":"multideposit",
"type":"com.dapr.event.sent"
},
"metadata":null,
"contentType":"application/cloudevents+json"
},
{
"entryId":"7ea8191e-1e62-46d0-9ba8-ff6e571351cc",
"event":{
"data":{
"amount":20,
"id":"17"
},
"datacontenttype":"application/json",
"id":"DaprClient",
"pubsubname":"pubsub",
"source":"Dapr",
"specversion":"1.0",
"topic":"multideposit",
"type":"com.dapr.event.sent"
},
"metadata":null,
"contentType":"application/cloudevents+json"
}
],
"id":"fa68c580-1b96-40d3-aa2c-04bab05e954e",
"metadata":{
"pubsubName":"pubsub"
},
"pubsubname":"pubsub",
"topic":"multideposit",
"type":"com.dapr.event.sent.bulk"
}'
```
Output:
```
{
"statuses":[
{
"entryId":"653dd9f5-f375-499b-8b2a-c4599bbd36b0",
"status":"SUCCESS"
},
{
"entryId":"7ea8191e-1e62-46d0-9ba8-ff6e571351cc",
"status":"SUCCESS"
}
]
}
```
---
**Withdraw Money**
On Linux, MacOS:
```sh
@ -135,7 +203,32 @@ On Windows:
dapr publish --pubsub pubsub --publish-app-id controller -t deposit -d "{\"id\": \"17\", \"amount\": 15 }"
```
---
**Dead Letter Topic example (pubsub)**
Publish an event using the Dapr cli with an incorrect input, i.e. negative amount:
Deposit:
On Linux, MacOS:
```sh
dapr publish --pubsub pubsub --publish-app-id controller -t deposit -d '{"id": "17", "amount": -15 }'
```
On Windows:
```sh
dapr publish --pubsub pubsub --publish-app-id controller -t deposit -d "{\"id\": \"17\", \"amount\": -15 }"
```
Withdraw:
On Linux, MacOS:
```sh
dapr publish --pubsub pubsub --publish-app-id controller -t withdraw -d '{"id": "17", "amount": -15 }'
```
On Windows:
```sh
dapr publish --pubsub pubsub --publish-app-id controller -t withdraw -d "{\"id\": \"17\", \"amount\": -15 }"
```
First a message is sent from a publisher on a `deposit` or `withdraw` topic. Dapr receives the message on behalf of a subscriber application, however the `deposit` or `withdraw` topic message fails to be delivered to the `/deposit` or `/withdraw` endpoint on the application, even after retries. As a result of the failure to deliver, the message is forwarded to the `amountDeadLetterTopic` topic which delivers this to the `/deadLetterTopicRoute` endpoint.
---
## Code Samples
*All of the interesting code in this sample is in Startup.cs and Controllers/SampleController.cs*
@ -190,6 +283,20 @@ public async Task<ActionResult<Account>> Deposit(...)
`[Topic(...)]` associates a pub/sub named `pubsub` (this is the default configured by the Dapr CLI) pub/sub topic `deposit` with this endpoint.
---
```C#
[Topic("pubsub", "multideposit", "amountDeadLetterTopic", false)]
[BulkSubscribe("multideposit")]
[HttpPost("multideposit")]
public async Task<ActionResult<BulkSubscribeAppResponse>> MultiDeposit([FromBody] BulkSubscribeMessage<BulkMessageModel<Transaction>>
bulkMessage, [FromServices] DaprClient daprClient)
```
`[BulkSubscribe(...)]` associates a topic with the name mentioned in the attribute with the ability to be bulk subscribed to. It can take additional parameters like `MaxMessagesCount` and `MaxAwaitDurationMs`.
If those parameters are not supplied, the defaults of 100 and 1000ms are set.
However, you need to use `BulkSubscribeMessage<BulkMessageModel<T>>` in the input and that you need to return the `BulkSubscribeAppResponse` as well.
---
```C#

View File

@ -1,11 +1,23 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
using Dapr;
using Dapr.AspNetCore;
namespace ControllerSample
{
using System.Text.Json;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
@ -54,7 +66,10 @@ namespace ControllerSample
app.UseRouting();
app.UseCloudEvents();
app.UseCloudEvents(new CloudEventsMiddlewareOptions
{
ForwardCloudEventPropertiesAsHeaders = true
});
app.UseAuthorization();

View File

@ -1,7 +1,15 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
namespace ControllerSample
{
@ -20,8 +28,7 @@ namespace ControllerSample
/// <summary>
/// Gets or sets amount for the transaction.
/// </summary>
[Range(0, double.MaxValue)]
/// </summary
public decimal Amount { get; set; }
}
}

View File

@ -1,7 +1,15 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
namespace ControllerSample
{

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6</TargetFramework>
<RunAnalyzersDuringBuild>true</RunAnalyzersDuringBuild>
</PropertyGroup>
@ -10,15 +10,16 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.30.0" />
<PackageReference Include="Google.Protobuf" Version="3.13.0" />
<PackageReference Include="Grpc.Net.Client" Version="2.32.0" />
<PackageReference Include="Grpc.Tools" Version="2.38.1" PrivateAssets="All" />
<PackageReference Include="Google.Api.CommonProtos" Version="2.2.0" />
<PackageReference Include="Google.Protobuf" />
<PackageReference Include="Grpc.AspNetCore" />
<PackageReference Include="Grpc.Net.Client" />
<PackageReference Include="Grpc.Tools" PrivateAssets="All" />
<PackageReference Include="Google.Api.CommonProtos" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Dapr.AspNetCore\Dapr.AspNetCore.csproj" />
<ProjectReference Include="..\..\..\src\Dapr.Protos\Dapr.Protos.csproj" />
</ItemGroup>
</Project>

View File

@ -1,7 +1,15 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
namespace GrpcServiceSample.Models
{

View File

@ -1,7 +1,15 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
namespace GrpcServiceSample.Models
{

View File

@ -1,7 +1,15 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
using System.ComponentModel.DataAnnotations;

View File

@ -1,13 +1,16 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.Hosting;

View File

@ -1,7 +1,15 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
syntax = "proto3";

View File

@ -11,7 +11,7 @@ The application also registers for pub/sub with the `deposit` and `withdraw` top
## Prerequisitess
- [.NET Core 3.1 or .NET 5+](https://dotnet.microsoft.com/download) installed
- [.NET 6+](https://dotnet.microsoft.com/download) installed
- [Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/)
- [Initialized Dapr environment](https://docs.dapr.io/getting-started/install-dapr-selfhost/)
- [Dapr .NET SDK](https://docs.dapr.io/developing-applications/sdks/dotnet/)

View File

@ -1,7 +1,15 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
using System;
using System.Text.Json;
@ -14,7 +22,7 @@ using Grpc.Core;
using GrpcServiceSample.Generated;
using Microsoft.Extensions.Logging;
namespace GrpcServiceSample
namespace GrpcServiceSample.Services
{
/// <summary>
/// BankAccount gRPC service

View File

@ -1,8 +1,18 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
using Dapr.AspNetCore;
using GrpcServiceSample.Services;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;

View File

@ -1,7 +1,15 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
namespace RoutingSample
{

View File

@ -1,7 +1,15 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
namespace RoutingSample
{

View File

@ -3,7 +3,7 @@
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:52186/",
"applicationUrl": "http://127.0.0.1:5000/",
"sslPort": 0
}
},

View File

@ -3,15 +3,16 @@
This sample shows using Dapr with ASP.NET Core routing. This application is a simple and not-so-secure banking application. The application uses the Dapr state-store for its data storage.
It exposes the following endpoints over HTTP:
- GET `/{id}`: Get the balance for the account specified by `id`
- POST `/deposit`: Accepts a JSON payload to deposit money to an account
- POST `/withdraw`: Accepts a JSON payload to withdraw money from an account
- GET `/{id}`: Get the balance for the account specified by `id`
- POST `/deposit`: Accepts a JSON payload to deposit money to an account
- POST `/multideposit`: Accepts a JSON payload to deposit money multiple times to a bulk subscribed topic
- POST `/withdraw`: Accepts a JSON payload to withdraw money from an account
The application also registers for pub/sub with the `deposit` and `withdraw` topics.
The application also registers for pub/sub with the `deposit`, `multideposit`, and `withdraw` topics.
## Prerequisites
- [.NET Core 3.1 or .NET 5+](https://dotnet.microsoft.com/download) installed
- [.NET 6+](https://dotnet.microsoft.com/download) installed
- [Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/)
- [Initialized Dapr environment](https://docs.dapr.io/getting-started/install-dapr-selfhost/)
- [Dapr .NET SDK](https://docs.dapr.io/developing-applications/sdks/dotnet/)
@ -25,8 +26,6 @@ The application also registers for pub/sub with the `deposit` and `withdraw` top
The application will listen on port 5000 for HTTP.
*Note: For Running the sample in ISS express, change the launchsettings.json to use 127.0.0.1 instead of localhost.*
### Examples
**Deposit Money**
@ -58,6 +57,76 @@ Output:
```
---
**Deposit Money multiple times to a bulk subscribed topic**
On Linux, MacOS:
```
curl -X POST http://127.0.0.1:5000/multideposit \
-H 'Content-Type: application/json' \
-d '{
"entries":[
{
"entryId":"653dd9f5-f375-499b-8b2a-c4599bbd36b0",
"event":{
"data":{
"amount":10,
"id":"17"
},
"datacontenttype":"application/json",
"id":"DaprClient",
"pubsubname":"pubsub",
"source":"Dapr",
"specversion":"1.0",
"topic":"multideposit",
"type":"com.dapr.event.sent"
},
"metadata":null,
"contentType":"application/cloudevents+json"
},
{
"entryId":"7ea8191e-1e62-46d0-9ba8-ff6e571351cc",
"event":{
"data":{
"amount":20,
"id":"17"
},
"datacontenttype":"application/json",
"id":"DaprClient",
"pubsubname":"pubsub",
"source":"Dapr",
"specversion":"1.0",
"topic":"multideposit",
"type":"com.dapr.event.sent"
},
"metadata":null,
"contentType":"application/cloudevents+json"
}
],
"id":"fa68c580-1b96-40d3-aa2c-04bab05e954e",
"metadata":{
"pubsubName":"pubsub"
},
"pubsubname":"pubsub",
"topic":"multideposit",
"type":"com.dapr.event.sent.bulk"
}'
```
Output:
```
{
"statuses":[
{
"entryId":"653dd9f5-f375-499b-8b2a-c4599bbd36b0",
"status":"SUCCESS"
},
{
"entryId":"7ea8191e-1e62-46d0-9ba8-ff6e571351cc",
"status":"SUCCESS"
}
]
}
```
---
**Withdraw Money**
On Linux, MacOS:
@ -133,7 +202,31 @@ On Windows:
dapr publish --pubsub pubsub --publish-app-id routing -t deposit -d "{\"id\": \"17\", \"amount\": 15 }"
```
---
**Dead Letter Topic example (pubsub)**
Publish an event using the Dapr cli with an incorrect input, i.e. negative amount:
Deposit:
On Linux, MacOS:
```sh
dapr publish --pubsub pubsub --publish-app-id routing -t deposit -d '{"id": "17", "amount": -15 }'
```
On Windows:
```sh
dapr publish --pubsub pubsub --publish-app-id routing -t deposit -d "{\"id\": \"17\", \"amount\": -15 }"
```
Withdraw:
On Linux, MacOS:
```sh
dapr publish --pubsub pubsub --publish-app-id routing -t withdraw -d '{"id": "17", "amount": -15 }'
```
On Windows:
```sh
dapr publish --pubsub pubsub --publish-app-id routing -t withdraw -d "{\"id\": \"17\", \"amount\": -15 }"
```
First a message is sent from a publisher on a `deposit` or `withdraw` topic. Dapr receives the message on behalf of a subscriber application, however the `deposit` or `withdraw` topic message fails to be delivered to the `/deposit` or `/withdraw` endpoint on the application, even after retries. As a result of the failure to deliver, the message is forwarded to the `amountDeadLetterTopic` topic which delivers this to the `/deadLetterTopicRoute` endpoint.
---
## Code Samples
*All of the interesting code in this sample is in Startup.cs*
@ -172,6 +265,7 @@ app.UseEndpoints(endpoints =>
endpoints.MapGet("{id}", Balance);
endpoints.MapPost("deposit", Deposit).WithTopic(PubsubName, "deposit");
endpoints.MapPost("multideposit", MultiDeposit).WithTopic(multiDepositTopicOptions).WithBulkSubscribe(bulkSubscribeTopicOptions);
endpoints.MapPost("withdraw", Withdraw).WithTopic(PubsubName, "withdraw");
});
```
@ -181,6 +275,28 @@ app.UseEndpoints(endpoints =>
`MapGet(...)` and `MapPost(...)` are provided by ASP.NET Core routing - these are used to setup endpoints to handle HTTP requests.
`WithTopic(...)` associates an endpoint with a pub/sub topic.
```C#
var depositTopicOptions = new TopicOptions();
depositTopicOptions.PubsubName = PubsubName;
depositTopicOptions.Name = "deposit";
depositTopicOptions.DeadLetterTopic = "amountDeadLetterTopic";
var withdrawTopicOptions = new TopicOptions();
withdrawTopicOptions.PubsubName = PubsubName;
withdrawTopicOptions.Name = "withdraw";
withdrawTopicOptions.DeadLetterTopic = "amountDeadLetterTopic";
var multiDepositTopicOptions = new TopicOptions
{ PubsubName = PubsubName, Name = "multideposit" };
var bulkSubscribeTopicOptions = new BulkSubscribeTopicOptions
{
TopicName = "multideposit", MaxMessagesCount = 250, MaxAwaitDurationMs = 1000
};
```
`WithTopic(...)` now takes the `TopicOptions(..)` instance that defines configurations for the subscribe endpoint.
`WithBulkSubscribe(...)` now takes the `BulkSubscribeTopicOptions(..)` instance that defines configurations for the bulk subscribe endpoint.
---

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6</TargetFramework>
</PropertyGroup>
<ItemGroup>

View File

@ -1,13 +1,24 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
namespace RoutingSample
{
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Threading.Tasks;
using Dapr;
using Dapr.AspNetCore;
using Dapr.Client;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
@ -15,6 +26,7 @@ namespace RoutingSample
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
/// <summary>
/// Startup class.
@ -66,7 +78,8 @@ namespace RoutingSample
/// <param name="app">Application builder.</param>
/// <param name="env">Webhost environment.</param>
/// <param name="serializerOptions">Options for JSON serialization.</param>
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, JsonSerializerOptions serializerOptions)
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, JsonSerializerOptions serializerOptions,
ILogger<Startup> logger)
{
if (env.IsDevelopment())
{
@ -81,27 +94,46 @@ namespace RoutingSample
{
endpoints.MapSubscribeHandler();
var depositTopicOptions = new TopicOptions();
depositTopicOptions.PubsubName = PubsubName;
depositTopicOptions.Name = "deposit";
depositTopicOptions.DeadLetterTopic = "amountDeadLetterTopic";
var withdrawTopicOptions = new TopicOptions();
withdrawTopicOptions.PubsubName = PubsubName;
withdrawTopicOptions.Name = "withdraw";
withdrawTopicOptions.DeadLetterTopic = "amountDeadLetterTopic";
var multiDepositTopicOptions = new TopicOptions { PubsubName = PubsubName, Name = "multideposit" };
var bulkSubscribeTopicOptions = new BulkSubscribeTopicOptions
{
TopicName = "multideposit", MaxMessagesCount = 250, MaxAwaitDurationMs = 1000
};
endpoints.MapGet("{id}", Balance);
endpoints.MapPost("deposit", Deposit).WithTopic(PubsubName, "deposit");
endpoints.MapPost("withdraw", Withdraw).WithTopic(PubsubName, "withdraw");
endpoints.MapPost("deposit", Deposit).WithTopic(depositTopicOptions);
endpoints.MapPost("multideposit", MultiDeposit).WithTopic(multiDepositTopicOptions).WithBulkSubscribe(bulkSubscribeTopicOptions);
endpoints.MapPost("deadLetterTopicRoute", ViewErrorMessage).WithTopic(PubsubName, "amountDeadLetterTopic");
endpoints.MapPost("withdraw", Withdraw).WithTopic(withdrawTopicOptions);
});
async Task Balance(HttpContext context)
{
Console.WriteLine("Enter Balance");
logger.LogInformation("Enter Balance");
var client = context.RequestServices.GetRequiredService<DaprClient>();
var id = (string)context.Request.RouteValues["id"];
Console.WriteLine("id is {0}", id);
logger.LogInformation("id is {0}", id);
var account = await client.GetStateAsync<Account>(StoreName, id);
if (account == null)
{
Console.WriteLine("Account not found");
logger.LogInformation("Account not found");
context.Response.StatusCode = 404;
return;
}
Console.WriteLine("Account balance is {0}", account.Balance);
logger.LogInformation("Account balance is {0}", account.Balance);
context.Response.ContentType = "application/json";
await JsonSerializer.SerializeAsync(context.Response.Body, account, serializerOptions);
@ -109,12 +141,13 @@ namespace RoutingSample
async Task Deposit(HttpContext context)
{
Console.WriteLine("Enter Deposit");
var client = context.RequestServices.GetRequiredService<DaprClient>();
logger.LogInformation("Enter Deposit");
var client = context.RequestServices.GetRequiredService<DaprClient>();
var transaction = await JsonSerializer.DeserializeAsync<Transaction>(context.Request.Body, serializerOptions);
Console.WriteLine("Id is {0}, Amount is {1}", transaction.Id, transaction.Amount);
logger.LogInformation("Id is {0}, Amount is {1}", transaction.Id, transaction.Amount);
var account = await client.GetStateAsync<Account>(StoreName, transaction.Id);
if (account == null)
{
@ -123,43 +156,105 @@ namespace RoutingSample
if (transaction.Amount < 0m)
{
Console.WriteLine("Invalid amount");
logger.LogInformation("Invalid amount");
context.Response.StatusCode = 400;
return;
}
account.Balance += transaction.Amount;
await client.SaveStateAsync(StoreName, transaction.Id, account);
Console.WriteLine("Balance is {0}", account.Balance);
logger.LogInformation("Balance is {0}", account.Balance);
context.Response.ContentType = "application/json";
await JsonSerializer.SerializeAsync(context.Response.Body, account, serializerOptions);
}
async Task MultiDeposit(HttpContext context)
{
logger.LogInformation("Enter bulk deposit");
var client = context.RequestServices.GetRequiredService<DaprClient>();
var bulkMessage = await JsonSerializer.DeserializeAsync<BulkSubscribeMessage<BulkMessageModel<Transaction>>>(
context.Request.Body, serializerOptions);
List<BulkSubscribeAppResponseEntry> entries = new List<BulkSubscribeAppResponseEntry>();
if (bulkMessage != null)
{
foreach (var entry in bulkMessage.Entries)
{
try
{
var transaction = entry.Event.Data;
var state = await client.GetStateEntryAsync<Account>(StoreName, transaction.Id);
state.Value ??= new Account() { Id = transaction.Id, };
logger.LogInformation("Id is {0}, the amount to be deposited is {1}",
transaction.Id, transaction.Amount);
if (transaction.Amount < 0m)
{
logger.LogInformation("Invalid amount");
context.Response.StatusCode = 400;
return;
}
state.Value.Balance += transaction.Amount;
logger.LogInformation("Balance is {0}", state.Value.Balance);
await state.SaveAsync();
entries.Add(new BulkSubscribeAppResponseEntry(entry.EntryId,
BulkSubscribeAppResponseStatus.SUCCESS));
}
catch (Exception e)
{
logger.LogError(e.Message);
entries.Add(new BulkSubscribeAppResponseEntry(entry.EntryId,
BulkSubscribeAppResponseStatus.RETRY));
}
}
}
await JsonSerializer.SerializeAsync(context.Response.Body,
new BulkSubscribeAppResponse(entries), serializerOptions);
}
async Task ViewErrorMessage(HttpContext context)
{
var transaction = await JsonSerializer.DeserializeAsync<Transaction>(context.Request.Body, serializerOptions);
logger.LogInformation("The amount cannot be negative: {0}", transaction.Amount);
return;
}
async Task Withdraw(HttpContext context)
{
Console.WriteLine("Enter Withdraw");
logger.LogInformation("Enter Withdraw");
var client = context.RequestServices.GetRequiredService<DaprClient>();
var transaction = await JsonSerializer.DeserializeAsync<Transaction>(context.Request.Body, serializerOptions);
Console.WriteLine("Id is {0}", transaction.Id);
logger.LogInformation("Id is {0}, Amount is {1}", transaction.Id, transaction.Amount);
var account = await client.GetStateAsync<Account>(StoreName, transaction.Id);
if (account == null)
{
Console.WriteLine("Account not found");
logger.LogInformation("Account not found");
context.Response.StatusCode = 404;
return;
}
if (transaction.Amount < 0m)
{
Console.WriteLine("Invalid amount");
logger.LogInformation("Invalid amount");
context.Response.StatusCode = 400;
return;
}
account.Balance -= transaction.Amount;
await client.SaveStateAsync(StoreName, transaction.Id, account);
Console.WriteLine("Balance is {0}", account.Balance);
logger.LogInformation("Balance is {0}", account.Balance);
context.Response.ContentType = "application/json";
await JsonSerializer.SerializeAsync(context.Response.Body, account, serializerOptions);

View File

@ -1,7 +1,15 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
namespace RoutingSample
{

View File

@ -1,3 +1,16 @@
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
namespace SecretStoreConfigurationProviderSample
{
using Microsoft.AspNetCore.Hosting;
@ -5,7 +18,7 @@
using Dapr.Client;
using Dapr.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Generic;
using System;
/// <summary>
/// Secret Store Configuration Provider Sample.
@ -49,7 +62,8 @@
// configBuilder.AddDaprSecretStore("demosecrets", secretDescriptors, client);
// Add the secret store Configuration Provider to the configuration builder.
configBuilder.AddDaprSecretStore("demosecrets", client);
// Including a TimeSpan allows us to dictate how long we should wait for the Sidecar to start.
configBuilder.AddDaprSecretStore("demosecrets", client, TimeSpan.FromSeconds(10));
})
.ConfigureWebHostDefaults(webBuilder =>
{

View File

@ -2,7 +2,7 @@
## Prerequisites
- [.NET Core 3.1 or .NET 5+](https://dotnet.microsoft.com/download) installed
- [.NET 6+](https://dotnet.microsoft.com/download) installed
- [Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/)
- [Initialized Dapr environment](https://docs.dapr.io/getting-started/install-dapr-selfhost/)
- [Dapr .NET SDK](https://docs.dapr.io/developing-applications/sdks/dotnet/)
@ -20,7 +20,7 @@ To load secrets into configuration call the _AddDaprSecretStore_ extension metho
Use Dapr to run the application:
```shell
dapr run --app-id SecretStoreConfigurationProviderSample --components-path ./components/ -- dotnet run
dapr run --app-id SecretStoreConfigurationProviderSample --resources-path ./components/ -- dotnet run
```
### 2. Test the application

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6</TargetFramework>
</PropertyGroup>
<ItemGroup>

View File

@ -1,3 +1,16 @@
// ------------------------------------------------------------------------
// Copyright 2021 The Dapr Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
namespace SecretStoreConfigurationProviderSample
{
using System.Text.Json;

View File

@ -0,0 +1,12 @@
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: redisconfig
spec:
type: configuration.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""

View File

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Dapr.Client\Dapr.Client.csproj" />
<ProjectReference Include="..\..\..\src\Dapr.AspNetCore\Dapr.AspNetCore.csproj" />
<ProjectReference Include="..\..\..\src\Dapr.Common\Dapr.Common.csproj" />
<ProjectReference Include="..\..\..\src\Dapr.Extensions.Configuration\Dapr.Extensions.Configuration.csproj" />
<ProjectReference Include="..\..\AspNetCore\ControllerSample\ControllerSample.csproj" />
</ItemGroup>
<ItemGroup>
<None Remove="Controllers\" />
</ItemGroup>
<ItemGroup>
<Folder Include="Controllers\" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,87 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using ControllerSample;
using Dapr;
using Dapr.Client;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace ConfigurationApi.Controllers
{
[ApiController]
[Route("configuration")]
public class ConfigurationController : ControllerBase
{
private ILogger<ConfigurationController> logger;
private IConfiguration configuration;
private DaprClient client;
public ConfigurationController(ILogger<ConfigurationController> logger, IConfiguration configuration, [FromServices] DaprClient client)
{
this.logger = logger;
this.configuration = configuration;
this.client = client;
}
[HttpGet("get/{configStore}/{queryKey}")]
public async Task GetConfiguration([FromRoute] string configStore, [FromRoute] string queryKey)
{
logger.LogInformation($"Querying Configuration with key: {queryKey}");
var configItems = await client.GetConfiguration(configStore, new List<string>() { queryKey });
if (configItems.Items.Count == 0)
{
logger.LogInformation($"No configuration item found for key: {queryKey}");
}
foreach (var item in configItems.Items)
{
logger.LogInformation($"Got configuration item:\nKey: {item.Key}\nValue: {item.Value.Value}\nVersion: {item.Value.Version}");
}
}
[HttpGet("extension")]
public Task SubscribeAndWatchConfiguration()
{
logger.LogInformation($"Getting values from Configuration Extension, watched values ['withdrawVersion', 'source'].");
logger.LogInformation($"'withdrawVersion' from extension: {configuration["withdrawVersion"]}");
logger.LogInformation($"'source' from extension: {configuration["source"]}");
return Task.CompletedTask;
}
#nullable enable
[HttpPost("withdraw")]
public async Task<ActionResult<Account>> CreateAccountHandler(Transaction transaction)
{
// Check if the V2 method is enabled.
if (configuration["withdrawVersion"] == "v2")
{
var source = !string.IsNullOrEmpty(configuration["source"]) ? configuration["source"] : "local";
var transactionV2 = new TransactionV2
{
Id = transaction.Id,
Amount = transaction.Amount,
Channel = source
};
logger.LogInformation($"Calling V2 Withdraw API - Id: {transactionV2.Id} Amount: {transactionV2.Amount} Channel: {transactionV2.Channel}");
try
{
return await this.client.InvokeMethodAsync<TransactionV2, Account>("controller", "withdraw.v2", transactionV2);
}
catch (DaprException ex)
{
logger.LogError($"Error executing withdrawal: {ex.Message}");
return BadRequest();
}
}
// Default to the original method.
logger.LogInformation($"Calling V1 Withdraw API: {transaction}");
return await this.client.InvokeMethodAsync<Transaction, Account>("controller", "withdraw", transaction);
}
#nullable disable
}
}

View File

@ -0,0 +1,41 @@
using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Dapr.Client;
using Dapr.Extensions.Configuration;
using System.Collections.Generic;
namespace ConfigurationApi
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Starting application.");
CreateHostBuilder(args).Build().Run();
Console.WriteLine("Closing application.");
}
/// <summary>
/// Creates WebHost Builder.
/// </summary>
/// <param name="args">Arguments.</param>
/// <returns>Returns IHostbuilder.</returns>
public static IHostBuilder CreateHostBuilder(string[] args)
{
var client = new DaprClientBuilder().Build();
return Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(config =>
{
// Get the initial value and continue to watch it for changes.
config.AddDaprConfigurationStore("redisconfig", new List<string>() { "withdrawVersion" }, client, TimeSpan.FromSeconds(20));
config.AddStreamingDaprConfigurationStore("redisconfig", new List<string>() { "withdrawVersion", "source" }, client, TimeSpan.FromSeconds(20));
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
}

View File

@ -0,0 +1,26 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:4855",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"ConfigurationApi": {
"commandName": "Project",
"applicationUrl": "http://localhost:5010",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More