Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ActorReference creation from the ActorBase class informations #1277

30 changes: 18 additions & 12 deletions src/Dapr.Actors/ActorReference.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// 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.
Expand All @@ -16,6 +16,7 @@ namespace Dapr.Actors
using System;
using System.Runtime.Serialization;
using Dapr.Actors.Client;
using Dapr.Actors.Runtime;

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

private static ActorReference GetActorReference(object actor)
{
if (actor == null)
{
throw new ArgumentNullException("actor");
}
ArgumentNullException.ThrowIfNull(actor, nameof(actor));

// try as IActorProxy for backward compatibility as customers's mock framework may rely on it before V2 remoting stack.
if (actor is IActorProxy actorProxy)
var actorReference = actor switch
{
return new ActorReference()
// try as IActorProxy for backward compatibility as customers's mock framework may rely on it before V2 remoting stack.
IActorProxy actorProxy => new ActorReference()
{
ActorId = actorProxy.ActorId,
ActorType = actorProxy.ActorType,
};
}
},
// Handle case when we want to get ActorReference inside the Actor implementation,
// we gather actor id and actor type from Actor base class.
Actor actorBase => new ActorReference()
{
ActorId = actorBase.Id,
ActorType = actorBase.Host.ActorTypeInfo.ActorTypeName,
},
// Handle case when we can't cast to IActorProxy or Actor.
_ => throw new ArgumentOutOfRangeException("actor", "Invalid actor object type."),
};

// TODO check for ActorBase
throw new ArgumentOutOfRangeException("actor");
return actorReference;
}
}
}
93 changes: 93 additions & 0 deletions test/Dapr.Actors.Test/ActorReferenceTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using System;
using System.Threading.Tasks;
using Dapr.Actors.Client;
using Dapr.Actors.Runtime;
using Dapr.Actors.Test;
using Xunit;

namespace Dapr.Actors
{
public class ActorReferenceTests
{
[Fact]
public void Get_WhenActorIsNull_ReturnsNull()
{
// Arrange
object actor = null;

// Act
var result = ActorReference.Get(actor);

// Assert
Assert.Null(result);
}

[Fact]
public void Get_FromActorProxy_ReturnsActorReference()
{
// Arrange
var expectedActorId = new ActorId("abc");
var expectedActorType = "TestActor";
var proxy = ActorProxy.Create(expectedActorId, typeof(ITestActor), expectedActorType);

// Act
var actorReference = ActorReference.Get(proxy);

// Assert
Assert.NotNull(actorReference);
Assert.Equal(expectedActorId, actorReference.ActorId);
Assert.Equal(expectedActorType, actorReference.ActorType);
}

[Fact]
public async Task Get_FromActorImplementation_ReturnsActorReference()
{
// Arrange
var expectedActorId = new ActorId("abc");
var expectedActorType = nameof(ActorReferenceTestActor);
var host = ActorHost.CreateForTest<ActorReferenceTestActor>(new ActorTestOptions() { ActorId = expectedActorId });
var actor = new ActorReferenceTestActor(host);

// Act
var actorReference = await actor.GetActorReference();

// Assert
Assert.NotNull(actorReference);
Assert.Equal(expectedActorId, actorReference.ActorId);
Assert.Equal(expectedActorType, actorReference.ActorType);
}

[Fact]
public void Get_WithInvalidObjectType_ThrowArgumentOutOfRangeException()
{
// Arrange
var actor = new object();

// Act
var act = () => ActorReference.Get(actor);

// Assert
var exception = Assert.Throws<ArgumentOutOfRangeException>(act);
Assert.Equal("actor", exception.ParamName);
Assert.Equal("Invalid actor object type. (Parameter 'actor')", exception.Message);
}
}

public interface IActorReferenceTestActor : IActor
{
Task<ActorReference> GetActorReference();
}

public class ActorReferenceTestActor : Actor, IActorReferenceTestActor
{
public ActorReferenceTestActor(ActorHost host)
: base(host)
{
}

public Task<ActorReference> GetActorReference()
{
return Task.FromResult(ActorReference.Get(this));
}
}
}
Loading