diff --git a/src/Akka.Hosting.TestKit.Tests/DiPropsFailTest.cs b/src/Akka.Hosting.TestKit.Tests/DiPropsFailTest.cs new file mode 100644 index 0000000..717dd8c --- /dev/null +++ b/src/Akka.Hosting.TestKit.Tests/DiPropsFailTest.cs @@ -0,0 +1,46 @@ +// ----------------------------------------------------------------------- +// +// Copyright (C) 2013-2023 .NET Foundation +// +// ----------------------------------------------------------------------- + +using System; +using Akka.Actor; +using Akka.DependencyInjection; +using Microsoft.Extensions.Logging; +using Xunit; +using Xunit.Abstractions; + +namespace Akka.Hosting.TestKit.Tests; + +// Regression test for https://github.com/akkadotnet/Akka.Hosting/issues/343 +public class DiPropsFailTest: TestKit +{ + public DiPropsFailTest(ITestOutputHelper output) : base(nameof(DiPropsFailTest), output) + {} + + protected override void ConfigureAkka(AkkaConfigurationBuilder builder, IServiceProvider provider) + { } + + [Fact] + public void DiTest() + { + var actor = Sys.ActorOf(NonRootActorWithDi.Props()); + actor.Tell("test"); + ExpectMsg("test"); + } + + private class NonRootActorWithDi: ReceiveActor + { + public static Props Props() => DependencyResolver.For(Context.System).Props(); + + public NonRootActorWithDi(ILogger log) + { + ReceiveAny(msg => + { + log.LogInformation("Received {Msg}", msg); + Sender.Tell(msg); + }); + } + } +} \ No newline at end of file diff --git a/src/Akka.Hosting.TestKit/ActorCellKeepingSynchronizationContext.cs b/src/Akka.Hosting.TestKit/ActorCellKeepingSynchronizationContext.cs deleted file mode 100644 index 004351d..0000000 --- a/src/Akka.Hosting.TestKit/ActorCellKeepingSynchronizationContext.cs +++ /dev/null @@ -1,83 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (C) 2009-2021 Lightbend Inc. -// Copyright (C) 2013-2021 .NET Foundation -// -//----------------------------------------------------------------------- - -using System; -using System.Threading; -using System.Threading.Tasks; -using Akka.Actor; -using Akka.Actor.Internal; - -namespace Akka.Hosting.TestKit -{ - /// - /// TBD - /// - class ActorCellKeepingSynchronizationContext : SynchronizationContext - { - private readonly ActorCell _cell; - - internal static ActorCell? AsyncCache { get; set; } - - /// - /// TBD - /// - /// TBD - public ActorCellKeepingSynchronizationContext(ActorCell cell) - { - _cell = cell; - } - - /// - /// TBD - /// - /// TBD - /// TBD - public override void Post(SendOrPostCallback d, object state) - { - ThreadPool.QueueUserWorkItem(_ => - { - var oldCell = InternalCurrentActorCellKeeper.Current; - var oldContext = Current; - SetSynchronizationContext(this); - InternalCurrentActorCellKeeper.Current = AsyncCache ?? _cell; - - try - { - d(state); - } - finally - { - InternalCurrentActorCellKeeper.Current = oldCell; - SetSynchronizationContext(oldContext); - } - }, state); - } - - /// - /// TBD - /// - /// TBD - /// TBD - public override void Send(SendOrPostCallback d, object state) - { - var tcs = new TaskCompletionSource(); - Post(_ => - { - try - { - d(state); - tcs.SetResult(0); - } - catch (Exception e) - { - tcs.TrySetException(e); - } - }, state); - tcs.Task.Wait(); - } - } -} diff --git a/src/Akka.Hosting.TestKit/TestKit.cs b/src/Akka.Hosting.TestKit/TestKit.cs index ad7818a..6759397 100644 --- a/src/Akka.Hosting.TestKit/TestKit.cs +++ b/src/Akka.Hosting.TestKit/TestKit.cs @@ -8,6 +8,7 @@ using System.Threading; using System.Threading.Tasks; using Akka.Actor; +using Akka.Actor.Internal; using Akka.Actor.Setup; using Akka.Annotations; using Akka.Configuration; @@ -53,7 +54,7 @@ public IHost Host public ITestOutputHelper? Output { get; } public LogLevel LogLevel { get; } - private TaskCompletionSource _initialized = new TaskCompletionSource(); + private readonly TaskCompletionSource _initialized = new TaskCompletionSource(); protected TestKit(string? actorSystemName = null, ITestOutputHelper? output = null, TimeSpan? startupTimeout = null, LogLevel logLevel = LogLevel.Information) : base(Assertions) @@ -102,8 +103,15 @@ private void InternalConfigureServices(HostBuilderContext context, IServiceColle builder.AddStartup((system, _) => { - base.InitializeTest(system, (ActorSystemSetup)null!, null, null); - _initialized.SetResult(Done.Instance); + try + { + base.InitializeTest(system, (ActorSystemSetup)null!, null, null); + _initialized.SetResult(Done.Instance); + } + catch (Exception e) + { + _initialized.SetException(e); + } }); }); } @@ -154,6 +162,10 @@ public async Task InitializeAsync() } await _initialized.Task; + + if (this is not INoImplicitSender && InternalCurrentActorCellKeeper.Current is null) + InternalCurrentActorCellKeeper.Current = (ActorCell)((ActorRefWithCell)TestActor).Underlying; + await BeforeTestStart(); }