Skip to content

Commit

Permalink
Add statically typed WithExtension method (#97)
Browse files Browse the repository at this point in the history
  • Loading branch information
Arkatufus authored Aug 29, 2022
1 parent db99763 commit 45a5c67
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
40 changes: 40 additions & 0 deletions src/Akka.Hosting.Tests/ExtensionsSpecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System;
using System.Threading.Tasks;
using Akka.Actor;
using Akka.Configuration;
using Akka.Event;
using Akka.TestKit.Xunit2.Internals;
using FluentAssertions;
Expand All @@ -16,6 +17,7 @@
using Xunit;
using Xunit.Abstractions;
using LogLevel = Microsoft.Extensions.Logging.LogLevel;
using static FluentAssertions.FluentActions;

namespace Akka.Hosting.Tests;

Expand Down Expand Up @@ -72,6 +74,44 @@ public async Task CanBeCalledMultipleTimes()
system.TryGetExtension<FakeExtensionTwo>(out _).Should().BeTrue();
}

[Fact(DisplayName = "WithExtensions with invalid type should throw")]
public void InvalidTypeShouldThrow()
{
Invoking(() =>
{
var builder = new AkkaConfigurationBuilder(new ServiceCollection(), "mySystem");
builder.WithExtensions(typeof(string));
}).Should().Throw<ConfigurationException>();
}

[Fact(DisplayName = "WithExtension should not override extensions declared in HOCON")]
public async Task WithExtensionShouldNotOverrideHocon()
{
using var host = await StartHost((builder, _) =>
{
builder.AddHocon("akka.extensions = [\"Akka.Hosting.Tests.ExtensionsSpecs+FakeExtensionOneProvider, Akka.Hosting.Tests\"]");
builder.WithExtension<FakeExtensionTwoProvider>();
});

var system = host.Services.GetRequiredService<ActorSystem>();
system.TryGetExtension<FakeExtensionOne>(out _).Should().BeTrue();
system.TryGetExtension<FakeExtensionTwo>(out _).Should().BeTrue();
}

[Fact(DisplayName = "WithExtension should be able to be called multiple times")]
public async Task WithExtensionCanBeCalledMultipleTimes()
{
using var host = await StartHost((builder, _) =>
{
builder.WithExtension<FakeExtensionOneProvider>();
builder.WithExtension<FakeExtensionTwoProvider>();
});

var system = host.Services.GetRequiredService<ActorSystem>();
system.TryGetExtension<FakeExtensionOne>(out _).Should().BeTrue();
system.TryGetExtension<FakeExtensionTwo>(out _).Should().BeTrue();
}

public class FakeExtensionOne: IExtension
{
}
Expand Down
23 changes: 23 additions & 0 deletions src/Akka.Hosting/AkkaConfigurationBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Akka.Actor;
using Akka.Actor.Dsl;
Expand Down Expand Up @@ -277,12 +278,34 @@ public AkkaConfigurationBuilder WithExtensions(params Type[] extensions)
{
foreach (var extension in extensions)
{
if (!typeof(IExtensionId).IsAssignableFrom(extension))
throw new ConfigurationException($"Type must extends {nameof(IExtensionId)}: [{extension.FullName}]");

var typeInfo = extension.GetTypeInfo();
if (typeInfo.IsAbstract || !typeInfo.IsClass)
throw new ConfigurationException("Type class must not be abstract or static");

if (Extensions.Contains(extension))
continue;
Extensions.Add(extension);
}
return this;
}

public AkkaConfigurationBuilder WithExtension<T>() where T : IExtensionId
{
var type = typeof(T);
if (Extensions.Contains(type))
return this;

var typeInfo = type.GetTypeInfo();
if (typeInfo.IsAbstract || !typeInfo.IsClass)
throw new ConfigurationException("Type class must not be abstract or static");

Extensions.Add(type);

return this;
}

internal void Bind()
{
Expand Down

0 comments on commit 45a5c67

Please sign in to comment.