Skip to content

Commit ddce8a2

Browse files
authored
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>
1 parent 8496253 commit ddce8a2

File tree

2 files changed

+111
-12
lines changed

2 files changed

+111
-12
lines changed

src/Dapr.Actors/ActorReference.cs

+18-12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// ------------------------------------------------------------------------
1+
// ------------------------------------------------------------------------
22
// Copyright 2021 The Dapr Authors
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@ namespace Dapr.Actors
1616
using System;
1717
using System.Runtime.Serialization;
1818
using Dapr.Actors.Client;
19+
using Dapr.Actors.Runtime;
1920

2021
/// <summary>
2122
/// Encapsulation of a reference to an actor for serialization.
@@ -69,23 +70,28 @@ public object Bind(Type actorInterfaceType)
6970

7071
private static ActorReference GetActorReference(object actor)
7172
{
72-
if (actor == null)
73-
{
74-
throw new ArgumentNullException("actor");
75-
}
73+
ArgumentNullException.ThrowIfNull(actor, nameof(actor));
7674

77-
// try as IActorProxy for backward compatibility as customers's mock framework may rely on it before V2 remoting stack.
78-
if (actor is IActorProxy actorProxy)
75+
var actorReference = actor switch
7976
{
80-
return new ActorReference()
77+
// try as IActorProxy for backward compatibility as customers's mock framework may rely on it before V2 remoting stack.
78+
IActorProxy actorProxy => new ActorReference()
8179
{
8280
ActorId = actorProxy.ActorId,
8381
ActorType = actorProxy.ActorType,
84-
};
85-
}
82+
},
83+
// Handle case when we want to get ActorReference inside the Actor implementation,
84+
// we gather actor id and actor type from Actor base class.
85+
Actor actorBase => new ActorReference()
86+
{
87+
ActorId = actorBase.Id,
88+
ActorType = actorBase.Host.ActorTypeInfo.ActorTypeName,
89+
},
90+
// Handle case when we can't cast to IActorProxy or Actor.
91+
_ => throw new ArgumentOutOfRangeException("actor", "Invalid actor object type."),
92+
};
8693

87-
// TODO check for ActorBase
88-
throw new ArgumentOutOfRangeException("actor");
94+
return actorReference;
8995
}
9096
}
9197
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
using Dapr.Actors.Client;
4+
using Dapr.Actors.Runtime;
5+
using Dapr.Actors.Test;
6+
using Xunit;
7+
8+
namespace Dapr.Actors
9+
{
10+
public class ActorReferenceTests
11+
{
12+
[Fact]
13+
public void Get_WhenActorIsNull_ReturnsNull()
14+
{
15+
// Arrange
16+
object actor = null;
17+
18+
// Act
19+
var result = ActorReference.Get(actor);
20+
21+
// Assert
22+
Assert.Null(result);
23+
}
24+
25+
[Fact]
26+
public void Get_FromActorProxy_ReturnsActorReference()
27+
{
28+
// Arrange
29+
var expectedActorId = new ActorId("abc");
30+
var expectedActorType = "TestActor";
31+
var proxy = ActorProxy.Create(expectedActorId, typeof(ITestActor), expectedActorType);
32+
33+
// Act
34+
var actorReference = ActorReference.Get(proxy);
35+
36+
// Assert
37+
Assert.NotNull(actorReference);
38+
Assert.Equal(expectedActorId, actorReference.ActorId);
39+
Assert.Equal(expectedActorType, actorReference.ActorType);
40+
}
41+
42+
[Fact]
43+
public async Task Get_FromActorImplementation_ReturnsActorReference()
44+
{
45+
// Arrange
46+
var expectedActorId = new ActorId("abc");
47+
var expectedActorType = nameof(ActorReferenceTestActor);
48+
var host = ActorHost.CreateForTest<ActorReferenceTestActor>(new ActorTestOptions() { ActorId = expectedActorId });
49+
var actor = new ActorReferenceTestActor(host);
50+
51+
// Act
52+
var actorReference = await actor.GetActorReference();
53+
54+
// Assert
55+
Assert.NotNull(actorReference);
56+
Assert.Equal(expectedActorId, actorReference.ActorId);
57+
Assert.Equal(expectedActorType, actorReference.ActorType);
58+
}
59+
60+
[Fact]
61+
public void Get_WithInvalidObjectType_ThrowArgumentOutOfRangeException()
62+
{
63+
// Arrange
64+
var actor = new object();
65+
66+
// Act
67+
var act = () => ActorReference.Get(actor);
68+
69+
// Assert
70+
var exception = Assert.Throws<ArgumentOutOfRangeException>(act);
71+
Assert.Equal("actor", exception.ParamName);
72+
Assert.Equal("Invalid actor object type. (Parameter 'actor')", exception.Message);
73+
}
74+
}
75+
76+
public interface IActorReferenceTestActor : IActor
77+
{
78+
Task<ActorReference> GetActorReference();
79+
}
80+
81+
public class ActorReferenceTestActor : Actor, IActorReferenceTestActor
82+
{
83+
public ActorReferenceTestActor(ActorHost host)
84+
: base(host)
85+
{
86+
}
87+
88+
public Task<ActorReference> GetActorReference()
89+
{
90+
return Task.FromResult(ActorReference.Get(this));
91+
}
92+
}
93+
}

0 commit comments

Comments
 (0)