Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions daprdocs/content/en/dotnet-sdk-docs/dotnet-actors/_index.md
Original file line number Diff line number Diff line change
@@ -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
description: Get up and running with the Dapr .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.
Original file line number Diff line number Diff line change
@@ -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:

Expand All @@ -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.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: It feels odd to refer to our own code as "error prone". I wonder what the background of this comment is and if we still need to fix it.

{{% /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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -91,4 +94,8 @@ 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.

## Next steps

[Learn how to author and run actors with `ActorHost`]({{< ref dotnet-actors-usage.md >}}).
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -26,11 +19,33 @@ 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)**

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 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 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.
**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

* **The actor client project(\MyActor\MyActorClient)** This project contains the implementation of the actor client which calls MyActor's method defined in Actor Interfaces.
- [Dapr CLI]({{< ref install-dapr-cli.md >}}) installed.
- Initialized [Dapr environment]({{< ref install-dapr-selfhost.md >}}).
- [.NET Core 3.1 or .NET 6+](https://dotnet.microsoft.com/download) installed. Dapr .NET SDK uses [ASP.NET Core](https://docs.microsoft.com/aspnet/core/introduction-to-aspnet-core?view=aspnetcore-6.0).

## Step 0: Prepare

Expand All @@ -42,9 +57,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

Expand Down
Loading