diff --git a/src/Dapr.Actors/Client/ActorProxyFactory.cs b/src/Dapr.Actors/Client/ActorProxyFactory.cs index 4a8fe3a08..399b0aa0a 100644 --- a/src/Dapr.Actors/Client/ActorProxyFactory.cs +++ b/src/Dapr.Actors/Client/ActorProxyFactory.cs @@ -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. @@ -11,14 +11,15 @@ // limitations under the License. // ------------------------------------------------------------------------ +using System; +using System.Globalization; +using System.Net.Http; +using Dapr.Actors.Builder; +using Dapr.Actors.Communication; +using Dapr.Actors.Communication.Client; + namespace Dapr.Actors.Client { - using System; - using System.Net.Http; - using Dapr.Actors.Builder; - using Dapr.Actors.Communication; - using Dapr.Actors.Communication.Client; - /// /// Represents a factory class to create a proxy to the remote actor objects. /// @@ -77,6 +78,16 @@ public ActorProxy Create(ActorId actorId, string actorType, ActorProxyOptions op /// public object CreateActorProxy(ActorId actorId, Type actorInterfaceType, string actorType, ActorProxyOptions options = null) { + if (!actorInterfaceType.IsAssignableFrom(actorInterfaceType)) + { + throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "The actor interface type '{0}' must implement IActor.", actorInterfaceType), nameof(actorInterfaceType)); + } + + if (!actorInterfaceType.IsVisible) + { + throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "The actor interface type '{0}' must be public.", actorInterfaceType), nameof(actorInterfaceType)); + } + options ??= this.DefaultOptions; var daprInteractor = new DaprHttpInteractor(this.handler, options.HttpEndpoint, options.DaprApiToken, options.RequestTimeout); diff --git a/test/Dapr.Actors.Test/ActorProxyTests.cs b/test/Dapr.Actors.Test/ActorProxyTests.cs index 078f4b5f6..da19d35fb 100644 --- a/test/Dapr.Actors.Test/ActorProxyTests.cs +++ b/test/Dapr.Actors.Test/ActorProxyTests.cs @@ -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. @@ -11,14 +11,14 @@ // limitations under the License. // ------------------------------------------------------------------------ +using System; +using System.Text.Json; +using Dapr.Actors.Test; +using FluentAssertions; +using Xunit; + namespace Dapr.Actors.Client { - using System; - using System.Text.Json; - using Dapr.Actors.Test; - using FluentAssertions; - using Xunit; - /// /// Test class for Actor Code builder. /// @@ -119,5 +119,41 @@ public void SetActorProxyFactoryDefaultOptions_ToNull_ThrowsArgumentNullExceptio action.Should().Throw(); } + + public interface INonActor + { + } + + [Fact] + public void CreateActorProxyForNonActorInterfaces() + { + var factory = new ActorProxyFactory(); + + var actorId = new ActorId("abc"); + + Assert.Throws(() => factory.CreateActorProxy(actorId, typeof(INonActor), "NonActor")); + } + + internal interface IInternalActor : IActor + { + } + + internal interface IInternalActor2 : IInternalActor + { + } + + [Fact] + public void CreateActorProxyForNonPublicActorInterfaces() + { + var factory = new ActorProxyFactory(); + + var actorId = new ActorId("abc"); + + Assert.Throws(() => factory.CreateActorProxy(actorId, "InternalActor")); + Assert.Throws(() => factory.CreateActorProxy(actorId, "InternalActor2")); + + Assert.Throws(() => factory.CreateActorProxy(actorId, typeof(IInternalActor), "InternalActor")); + Assert.Throws(() => factory.CreateActorProxy(actorId, typeof(IInternalActor2), "InternalActor2")); + } } }