-
Notifications
You must be signed in to change notification settings - Fork 1k
/
DelegateInjectionSpecs.cs
136 lines (112 loc) · 4.49 KB
/
DelegateInjectionSpecs.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//-----------------------------------------------------------------------
// <copyright file="DelegateInjectionSpecs.cs" company="Akka.NET Project">
// Copyright (C) 2009-2021 Lightbend Inc. <http://www.lightbend.com>
// Copyright (C) 2013-2021 .NET Foundation <https://github.com/akkadotnet/akka.net>
// </copyright>
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Akka.Actor;
using Akka.TestKit;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Xunit;
using Xunit.Abstractions;
namespace Akka.DependencyInjection.Tests
{
public class DelegateInjectionSpecs : AkkaSpec
{
public delegate IActorRef EchoActorProvider();
private readonly IServiceProvider _serviceProvider;
public static IServiceProvider CreateProvider()
{
var services = new ServiceCollection()
.AddSingleton<AkkaService>()
.AddHostedService<AkkaService>()
.AddSingleton<EchoActorProvider>(p =>
{
var system = p.GetRequiredService<AkkaService>();
var actor = system.ActorSystem.ActorOf<EchoActor>("echoActor");
return () => actor;
});
var provider = services.BuildServiceProvider();
var akkaService = provider.GetRequiredService<AkkaService>();
akkaService.StartAsync(default).Wait();
return provider;
}
public DelegateInjectionSpecs(ITestOutputHelper output) : base(output)
{
_serviceProvider = CreateProvider();
}
[Fact]
public async Task DI_should_be_able_to_retrieve_singleton_using_delegate()
{
var actor = _serviceProvider.GetRequiredService<EchoActorProvider>()();
var task = actor.Ask("echo");
task.Wait(TimeSpan.FromSeconds(3));
task.Result.ShouldBe("echo");
var sys = _serviceProvider.GetRequiredService<AkkaService>().ActorSystem;
await sys.Terminate();
}
[Fact]
public async Task DI_should_be_able_to_retrieve_singleton_using_delegate_from_inside_actor()
{
var system = _serviceProvider.GetRequiredService<AkkaService>().ActorSystem;
var actor = system.ActorOf(ParentActor.Props(system));
var task = actor.Ask("echo");
task.Wait(TimeSpan.FromSeconds(3));
task.Result.ShouldBe("echo");
var sys = _serviceProvider.GetRequiredService<AkkaService>().ActorSystem;
await sys.Terminate();
}
internal class ParentActor : UntypedActor
{
public static Props Props(ActorSystem system) =>
DependencyResolver.For(system).Props<ParentActor>();
private readonly IActorRef _echoActor;
public ParentActor(IServiceProvider provider)
{
_echoActor = provider.GetRequiredService<EchoActorProvider>()();
}
protected override void OnReceive(object message)
{
_echoActor.Forward(message);
}
}
internal class EchoActor : ReceiveActor
{
public static Props Props() => Akka.Actor.Props.Create<EchoActor>();
public EchoActor()
{
Receive<string>(msg =>
{
Sender.Tell(msg);
});
}
}
internal class AkkaService : IHostedService
{
public ActorSystem ActorSystem { get; private set; }
private readonly IServiceProvider _serviceProvider;
public AkkaService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public Task StartAsync(CancellationToken cancellationToken)
{
var setup = DependencyResolverSetup.Create(_serviceProvider)
.And(BootstrapSetup.Create().WithConfig(TestKitBase.DefaultConfig));
ActorSystem = ActorSystem.Create("TestSystem", setup);
return Task.CompletedTask;
}
public async Task StopAsync(CancellationToken cancellationToken)
{
await ActorSystem.Terminate();
}
}
}
}