diff --git a/src/core/Akka.TestKit/TestKitBase_ActorOf.cs b/src/core/Akka.TestKit/TestKitBase_ActorOf.cs
index 15ef754b4db..a14f1a7e4c9 100644
--- a/src/core/Akka.TestKit/TestKitBase_ActorOf.cs
+++ b/src/core/Akka.TestKit/TestKitBase_ActorOf.cs
@@ -6,7 +6,6 @@
//-----------------------------------------------------------------------
using System;
-using System.Linq.Expressions;
using Akka.Actor;
using Akka.Actor.Dsl;
@@ -71,7 +70,7 @@ public IActorRef ActorOf(Props props, string name)
/// The type of the actor.
/// An expression that calls the constructor of
/// TBD
- public IActorRef ActorOf(Expression> factory) where TActor : ActorBase
+ public IActorRef ActorOf(Func factory) where TActor : ActorBase
{
return Sys.ActorOf(Props.Create(factory), null);
}
@@ -87,7 +86,7 @@ public IActorRef ActorOf(Expression> factory) where TActor
/// An expression that calls the constructor of
/// The name of the actor.
/// TBD
- public IActorRef ActorOf(Expression> factory, string name) where TActor : ActorBase
+ public IActorRef ActorOf(Func factory, string name) where TActor : ActorBase
{
return Sys.ActorOf(Props.Create(factory), name);
}
@@ -201,7 +200,7 @@ public TestActorRef ActorOfAsTestActorRef(Props props, string na
/// The supervisor
/// Optional: The name.
/// TBD
- public TestActorRef ActorOfAsTestActorRef(Expression> factory, IActorRef supervisor, string name = null) where TActor : ActorBase
+ public TestActorRef ActorOfAsTestActorRef(Func factory, IActorRef supervisor, string name = null) where TActor : ActorBase
{
return new TestActorRef(Sys, Props.Create(factory), supervisor, name);
}
@@ -218,7 +217,7 @@ public TestActorRef ActorOfAsTestActorRef(ExpressionAn expression that calls the constructor of
/// Optional: The name.
/// TBD
- public TestActorRef ActorOfAsTestActorRef(Expression> factory, string name = null) where TActor : ActorBase
+ public TestActorRef ActorOfAsTestActorRef(Func factory, string name = null) where TActor : ActorBase
{
return new TestActorRef(Sys, Props.Create(factory), NoSupervisor, name);
}
@@ -333,7 +332,7 @@ public TestFSMRef ActorOfAsTestFSMRefOptional: The name.
/// Optional: If set to true logs state changes of the FSM as Debug messages. Default is false.
/// TBD
- public TestFSMRef ActorOfAsTestFSMRef(Expression> factory, IActorRef supervisor, string name = null, bool withLogging = false)
+ public TestFSMRef ActorOfAsTestFSMRef(Func factory, IActorRef supervisor, string name = null, bool withLogging = false)
where TFsmActor : FSM
{
return new TestFSMRef(Sys, Props.Create(factory), supervisor, name, withLogging);
@@ -351,7 +350,7 @@ public TestFSMRef ActorOfAsTestFSMRefOptional: The name.
/// Optional: If set to true logs state changes of the FSM as Debug messages. Default is false.
/// TBD
- public TestFSMRef ActorOfAsTestFSMRef(Expression> factory, string name = null, bool withLogging = false)
+ public TestFSMRef ActorOfAsTestFSMRef(Func factory, string name = null, bool withLogging = false)
where TFsmActor : FSM
{
return new TestFSMRef(Sys, Props.Create(factory), NoSupervisor, name, withLogging);
diff --git a/src/core/Akka/Actor/Props.cs b/src/core/Akka/Actor/Props.cs
index cf86531a0fe..cb88b9db1fe 100644
--- a/src/core/Akka/Actor/Props.cs
+++ b/src/core/Akka/Actor/Props.cs
@@ -1,4 +1,4 @@
-//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
//
// Copyright (C) 2009-2022 Lightbend Inc.
// Copyright (C) 2013-2025 .NET Foundation
@@ -8,13 +8,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Linq.Expressions;
-using Akka.Configuration;
using Akka.Dispatch;
using Akka.Routing;
using Akka.Util;
-using Akka.Util.Internal;
-using Akka.Util.Reflection;
using Newtonsoft.Json;
namespace Akka.Actor
@@ -46,8 +42,6 @@ public class Props : IEquatable, ISurrogated
///
///
public static readonly Props None = null;
- private Type _inputType;
- private Type _outputType;
private readonly IIndirectActorProducer _producer;
///
@@ -163,13 +157,12 @@ public Props(Deploy deploy, Type type, IEnumerable
public string TypeName
{
- get => _inputType.AssemblyQualifiedName;
- //for serialization
- private set => _inputType = Type.GetType(value);
+ get => _producer.ActorType.AssemblyQualifiedName;
+ //private set => _producer.ActorType = Type.GetType(value);
}
///
@@ -283,7 +272,7 @@ public ISurrogate ToSurrogate(ActorSystem system)
private bool CompareInputType(Props other)
{
- return _inputType == other._inputType;
+ return _producer.ActorType == other._producer.ActorType;
}
private bool CompareDeploy(Props other)
@@ -328,7 +317,6 @@ public override bool Equals(object obj)
return Equals((Props)obj);
}
-
public override int GetHashCode()
{
unchecked
@@ -336,7 +324,7 @@ public override int GetHashCode()
var hashCode = Deploy != null ? Deploy.GetHashCode() : 0;
// hashCode = (hashCode*397) ^ (SupervisorStrategy != null ? SupervisorStrategy.GetHashCode() : 0);
// hashCode = (hashCode*397) ^ (Arguments != null ? Arguments.GetHashCode() : 0);
- hashCode = (hashCode * 397) ^ (_inputType != null ? _inputType.GetHashCode() : 0);
+ hashCode = (hashCode * 397) ^ (_producer.ActorType != null ? _producer.ActorType.GetHashCode() : 0);
return hashCode;
}
}
@@ -349,53 +337,30 @@ public override int GetHashCode()
/// Optional: The supervisor strategy used to manage the actor.
/// The newly created .
/// The create function must be a 'new T (args)' expression
- public static Props Create(Expression> factory,
- SupervisorStrategy supervisorStrategy = null) where TActor : ActorBase
+ public static Props Create(Func factory, SupervisorStrategy supervisorStrategy = null) where TActor : ActorBase
{
- if (factory.Body is UnaryExpression)
- return new DynamicProps(factory.Compile());
-
- var newExpression = factory.Body.AsInstanceOf();
- if (newExpression == null)
- throw new ArgumentException("The create function must be a 'new T (args)' expression");
-
- var args = newExpression.Arguments.Count > 0 ? newExpression.GetArguments() : NoArgs;
-
- return new Props(new ActivatorProducer(typeof(TActor), args), DefaultDeploy, args){ SupervisorStrategy = supervisorStrategy };
+ return new Props(new FactoryProducer(factory), DefaultDeploy, NoArgs) { SupervisorStrategy = supervisorStrategy };
}
///
/// Creates an actor using the given arguments.
///
/// The type of the actor to create.
- /// The arguments needed to create the actor.
- /// The newly created .
- public static Props Create(params object[] args) where TActor : ActorBase
- {
- return new Props(new ActivatorProducer(typeof(TActor), args), DefaultDeploy, args);
- }
-
- ///
- /// Creates an actor using a specified actor producer.
- ///
- /// The type of producer used to create the actor.
- /// The arguments needed to create the actor.
/// The newly created .
- [Obsolete("Do not use this method. Call CreateBy(IIndirectActorProducer, params object[] args) instead")]
- public static Props CreateBy(params object[] args) where TProducer : class, IIndirectActorProducer
+ public static Props Create() where TActor : ActorBase, new()
{
- return new Props(typeof(TProducer), args);
+ return new Props(new FactoryProducer(() => new TActor()), DefaultDeploy, NoArgs);
}
///
- /// Creates an actor using a specified actor producer.
+ /// Creates an actor using the given arguments.
///
- /// The actor producer that will be used to create the underlying actor..
+ /// The type of the actor to create.
/// The arguments needed to create the actor.
/// The newly created .
- public static Props CreateBy(IIndirectActorProducer producer, params object[] args)
+ public static Props Create(params object[] args) where TActor : ActorBase
{
- return new Props(producer, DefaultDeploy, args);
+ return new Props(new ActivatorProducer(typeof(TActor), args), DefaultDeploy, args);
}
///
@@ -406,7 +371,7 @@ public static Props CreateBy(IIndirectActorProducer producer, params object[] ar
/// The newly created .
public static Props Create(SupervisorStrategy supervisorStrategy) where TActor : ActorBase, new()
{
- return new Props(new ActivatorProducer(typeof(TActor), NoArgs), DefaultDeploy, NoArgs){ SupervisorStrategy = supervisorStrategy };
+ return new Props(new FactoryProducer(() => new TActor()), DefaultDeploy, NoArgs) { SupervisorStrategy = supervisorStrategy };
}
///
@@ -424,6 +389,29 @@ public static Props Create(Type type, params object[] args)
return new Props(type, args);
}
+ ///
+ /// Creates an actor using a specified actor producer.
+ ///
+ /// The type of producer used to create the actor.
+ /// The arguments needed to create the actor.
+ /// The newly created .
+ [Obsolete("Do not use this method. Call CreateBy(IIndirectActorProducer, params object[] args) instead")]
+ public static Props CreateBy(params object[] args) where TProducer : class, IIndirectActorProducer
+ {
+ return new Props(typeof(TProducer), args);
+ }
+
+ ///
+ /// Creates an actor using a specified actor producer.
+ ///
+ /// The actor producer that will be used to create the underlying actor..
+ /// The arguments needed to create the actor.
+ /// The newly created .
+ public static Props CreateBy(IIndirectActorProducer producer, params object[] args)
+ {
+ return new Props(producer, DefaultDeploy, args);
+ }
+
///
/// Creates a new with a given .
///
@@ -468,7 +456,7 @@ public Props WithRouter(RouterConfig routerConfig)
copy.Deploy = Deploy.WithRouterConfig(routerConfig);
return copy;
}
-
+
///
/// Creates a new with a given stash size.
///
@@ -499,12 +487,13 @@ public Props WithStashCapacity(int stashCapacity)
public Props WithDeploy(Deploy deploy)
{
var copy = Copy();
- var original = copy.Deploy;
+ //var original = copy.Deploy;
// TODO: this is a hack designed to preserve explicit router deployments https://github.com/akkadotnet/akka.net/issues/546
// in reality, we should be able to do copy.Deploy = deploy.WithFallback(copy.Deploy); but that blows up at the moment
// - Aaron Stannard
copy.Deploy = deploy.WithFallback(copy.Deploy);
+
//if (!(original.RouterConfig is NoRouter || original.RouterConfig is FromConfig) && deploy.RouterConfig is NoRouter)
//{
// copy.Deploy = deploy.WithFallback(copy.Deploy);
@@ -555,17 +544,13 @@ public Props WithSupervisorStrategy(SupervisorStrategy supervisorStrategy)
/// The newly created actor
public virtual ActorBase NewActor()
{
- var type = Type;
- var arguments = Arguments;
try
{
return _producer.Produce();
}
catch (Exception e)
{
- throw new TypeLoadException(
- $"Error while creating actor instance of type {type} with {arguments.Length} args: ({StringFormat.SafeJoin(",", arguments)})",
- e);
+ throw new TypeLoadException($"Error while creating actor instance of type {Type} with {Arguments.Length} args: ({StringFormat.SafeJoin(",", Arguments)})", e);
}
}
@@ -578,23 +563,6 @@ protected virtual Props Copy()
return new Props(_producer, Deploy, Arguments) { SupervisorStrategy = SupervisorStrategy };
}
- [Obsolete("we should not be calling this method. Pass in an explicit IIndirectActorProducer reference instead.")]
- private static IIndirectActorProducer CreateProducer(Type type, object[] args)
- {
- if (type == null) return DefaultProducer.Instance;
-
- if (typeof(IIndirectActorProducer).IsAssignableFrom(type))
- return Activator.CreateInstance(type, args).AsInstanceOf();
-
- if (typeof(ActorBase).IsAssignableFrom(type)) return new ActivatorProducer(type, args);
-
- throw new ArgumentException($"Unknown actor producer [{type.FullName}]", nameof(type));
- }
-
- ///
- /// Signals the producer that it can release its reference to the actor.
- ///
- /// The actor to release
internal void Release(ActorBase actor)
{
try
@@ -655,26 +623,6 @@ protected override void OnReceive(object message)
}
}
- private class DefaultProducer : IIndirectActorProducer
- {
- private DefaultProducer(){}
-
- public static readonly DefaultProducer Instance = new();
-
- public ActorBase Produce()
- {
- throw new InvalidOperationException("No actor producer specified!");
- }
-
- public Type ActorType => typeof(ActorBase);
-
-
- public void Release(ActorBase actor)
- {
- actor = null;
- }
- }
-
private class ActivatorProducer : IIndirectActorProducer
{
private readonly object[] _args;
@@ -687,23 +635,22 @@ public ActivatorProducer(Type actorType, object[] args)
public ActorBase Produce()
{
- return Activator.CreateInstance(ActorType, _args).AsInstanceOf();
+ return (ActorBase)Activator.CreateInstance(ActorType, _args);
}
public Type ActorType { get; }
-
public void Release(ActorBase actor)
{
actor = null;
}
}
- private class FactoryConsumer : IIndirectActorProducer where TActor : ActorBase
+ private class FactoryProducer : IIndirectActorProducer where TActor : ActorBase
{
private readonly Func _factory;
- public FactoryConsumer(Func factory)
+ public FactoryProducer(Func factory)
{
_factory = factory;
}
@@ -715,7 +662,6 @@ public ActorBase Produce()
public Type ActorType => typeof(TActor);
-
public void Release(ActorBase actor)
{
actor = null;
@@ -751,7 +697,7 @@ public override ActorBase NewActor()
/// The type of the actor to create.
internal class DynamicProps : Props where TActor : ActorBase
{
- private readonly Func invoker;
+ private readonly Func _invoker;
///
/// Initializes a new instance of the class.
@@ -760,7 +706,7 @@ internal class DynamicProps : Props where TActor : ActorBase
public DynamicProps(Func invoker)
: base(typeof(TActor))
{
- this.invoker = invoker;
+ this._invoker = invoker;
}
///
@@ -769,7 +715,7 @@ public DynamicProps(Func invoker)
/// The actor created using the factory method.
public override ActorBase NewActor()
{
- return invoker.Invoke();
+ return _invoker.Invoke();
}
#region Copy methods
@@ -777,7 +723,7 @@ public override ActorBase NewActor()
private DynamicProps(Props copy, Func invoker)
: base(copy)
{
- this.invoker = invoker;
+ this._invoker = invoker;
}
///
@@ -787,7 +733,7 @@ private DynamicProps(Props copy, Func invoker)
protected override Props Copy()
{
var initialCopy = base.Copy();
- var invokerCopy = (Func)invoker.Clone();
+ var invokerCopy = (Func)_invoker.Clone();
return new DynamicProps(initialCopy, invokerCopy);
}
@@ -828,4 +774,4 @@ public interface IIndirectActorProducer
/// The actor to release
void Release(ActorBase actor);
}
-}
+}
\ No newline at end of file