Skip to content

Commit

Permalink
Add missing IStatsDPublisherWithTags registration
Browse files Browse the repository at this point in the history
- Add missing IoC registration for `IStatsDPublisherWithTags`.
- Mention `IStatsDPublisherWithTags` in the README.
- Tidy up some redundant checks in the unit tests as the container always implements `IDisposable`..

Resolves #661.
  • Loading branch information
martincostello committed Apr 23, 2024
1 parent 8400146 commit c59f171
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 153 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ We use this library within our components to publish [StatsD](https://github.com

#### Publishing statistics

`IStatsDPublisher` is the interface that you will use to send stats. The concrete class that implements `IStatsDPublisher` is `StatsDPublisher`. The `StatsDPublisher` constructor takes an instance of `StatsDConfiguration`.
`IStatsDPublisher` is the interface that you will use to send stats. There is also a `IStatsDPublisherWithTags` interface that can be used to send stats with tags.

The concrete class that implements `IStatsDPublisher` is `StatsDPublisher`. The `StatsDPublisher` constructor takes an instance of `StatsDConfiguration`.

For the configuration's values, you will always need the StatsD server host name or IP address. Optionally, you can also change the port from the default (`8125`). You can also prepend a prefix to all stats. These values often come from configuration as the host name and/or prefix may vary between test and production environments.

Expand Down
5 changes: 4 additions & 1 deletion src/JustEat.StatsD/StatsDServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ private static IServiceCollection AddStatsDCore(this IServiceCollection services
{
services.TryAddSingleton(ResolveEndPointSource);
services.TryAddSingleton(ResolveStatsDTransport);

services.TryAddSingleton(ResolveStatsDPublisher);
services.TryAddSingleton<IStatsDPublisher>((p) => p.GetRequiredService<StatsDPublisher>());
services.TryAddSingleton<IStatsDPublisherWithTags>((p) => p.GetRequiredService<StatsDPublisher>());

return services;
}
Expand All @@ -115,7 +118,7 @@ private static IEndPointSource ResolveEndPointSource(IServiceProvider provider)
config.DnsLookupInterval);
}

private static IStatsDPublisher ResolveStatsDPublisher(IServiceProvider provider)
private static StatsDPublisher ResolveStatsDPublisher(IServiceProvider provider)
{
var config = provider.GetRequiredService<StatsDConfiguration>();
var socketProtocol = provider.GetRequiredService<IStatsDTransport>();
Expand Down
273 changes: 122 additions & 151 deletions tests/JustEat.StatsD.Tests/WhenRegisteringStatsD.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,35 @@ public static void CanRegisterServicesWithNoConfigurationIfConfigurationAlreadyR
Host = "localhost"
};

var provider = Configure(services =>
{
services.AddSingleton(config);
using var provider = Configure(services =>
{
services.AddSingleton(config);
// Act
services.AddStatsD();
});
// Act
services.AddStatsD();
});

try
{
// Assert
var configuration = provider.GetRequiredService<StatsDConfiguration>();
configuration.ShouldNotBeNull();
configuration.ShouldBe(config);
// Assert
var configuration = provider.GetRequiredService<StatsDConfiguration>();
configuration.ShouldNotBeNull();
configuration.ShouldBe(config);

var source = provider.GetRequiredService<IEndPointSource>();
source.ShouldNotBeNull();
var source = provider.GetRequiredService<IEndPointSource>();
source.ShouldNotBeNull();

var transport = provider.GetRequiredService<IStatsDTransport>();
transport.ShouldNotBeNull();
transport.ShouldBeOfType<SocketTransport>();
var transport = provider.GetRequiredService<IStatsDTransport>();
transport.ShouldNotBeNull();
transport.ShouldBeOfType<SocketTransport>();

var publisher = provider.GetRequiredService<IStatsDPublisher>();
publisher.ShouldNotBeNull();
publisher.ShouldBeOfType<StatsDPublisher>();
}
finally
{
if (provider is IDisposable disposable)
{
disposable.Dispose();
}
}
var publisher = provider.GetRequiredService<IStatsDPublisher>();
publisher.ShouldNotBeNull();
publisher.ShouldBeOfType<StatsDPublisher>();

var publisherWithTags = provider.GetRequiredService<IStatsDPublisherWithTags>();
publisherWithTags.ShouldNotBeNull();
publisherWithTags.ShouldBeOfType<StatsDPublisher>();

publisherWithTags.ShouldBeSameAs(publisher);
}

[Fact]
Expand All @@ -56,38 +52,28 @@ public static void CanRegisterServicesWithAHost()
// Arrange
string host = "localhost";

var provider = Configure(services =>
{
// Act
services.AddStatsD(host);
});

try
{
// Assert
var configuration = provider.GetRequiredService<StatsDConfiguration>();
configuration.ShouldNotBeNull();
configuration.Host.ShouldBe(host);
configuration.Prefix.ShouldBeEmpty();

var source = provider.GetRequiredService<IEndPointSource>();
source.ShouldNotBeNull();

var transport = provider.GetRequiredService<IStatsDTransport>();
transport.ShouldNotBeNull();
transport.ShouldBeOfType<SocketTransport>();

var publisher = provider.GetRequiredService<IStatsDPublisher>();
publisher.ShouldNotBeNull();
publisher.ShouldBeOfType<StatsDPublisher>();
}
finally
using var provider = Configure(services =>
{
if (provider is IDisposable disposable)
{
disposable.Dispose();
}
}
// Act
services.AddStatsD(host);
});

// Assert
var configuration = provider.GetRequiredService<StatsDConfiguration>();
configuration.ShouldNotBeNull();
configuration.Host.ShouldBe(host);
configuration.Prefix.ShouldBeEmpty();

var source = provider.GetRequiredService<IEndPointSource>();
source.ShouldNotBeNull();

var transport = provider.GetRequiredService<IStatsDTransport>();
transport.ShouldNotBeNull();
transport.ShouldBeOfType<SocketTransport>();

var publisher = provider.GetRequiredService<IStatsDPublisher>();
publisher.ShouldNotBeNull();
publisher.ShouldBeOfType<StatsDPublisher>();
}

[Fact]
Expand All @@ -97,38 +83,28 @@ public static void CanRegisterServicesWithAHostAndPrefix()
string host = "localhost";
string prefix = "myprefix";

var provider = Configure(services =>
{
// Act
services.AddStatsD(host, prefix);
});

try
using var provider = Configure(services =>
{
// Assert
var configuration = provider.GetRequiredService<StatsDConfiguration>();
configuration.ShouldNotBeNull();
configuration.Host.ShouldBe(host);
configuration.Prefix.ShouldBe(prefix);

var source = provider.GetRequiredService<IEndPointSource>();
source.ShouldNotBeNull();

var transport = provider.GetRequiredService<IStatsDTransport>();
transport.ShouldNotBeNull();
transport.ShouldBeOfType<SocketTransport>();

var publisher = provider.GetRequiredService<IStatsDPublisher>();
publisher.ShouldNotBeNull();
publisher.ShouldBeOfType<StatsDPublisher>();
}
finally
{
if (provider is IDisposable disposable)
{
disposable.Dispose();
}
}
// Act
services.AddStatsD(host, prefix);
});

// Assert
var configuration = provider.GetRequiredService<StatsDConfiguration>();
configuration.ShouldNotBeNull();
configuration.Host.ShouldBe(host);
configuration.Prefix.ShouldBe(prefix);

var source = provider.GetRequiredService<IEndPointSource>();
source.ShouldNotBeNull();

var transport = provider.GetRequiredService<IStatsDTransport>();
transport.ShouldNotBeNull();
transport.ShouldBeOfType<SocketTransport>();

var publisher = provider.GetRequiredService<IStatsDPublisher>();
publisher.ShouldNotBeNull();
publisher.ShouldBeOfType<StatsDPublisher>();
}

[Fact]
Expand All @@ -140,48 +116,38 @@ public static void CanRegisterServicesWithFactoryMethod()
StatsDHost = "localhost"
};

var provider = Configure(services =>
using var provider = Configure(services =>
{
services.AddSingleton(options);
// Act
services.AddStatsD(serviceProvider =>
{
services.AddSingleton(options);
// Act
services.AddStatsD(serviceProvider =>
{
var myOptions = serviceProvider.GetRequiredService<MyOptions>();
return new StatsDConfiguration
{
Host = myOptions.StatsDHost
};
});
var myOptions = serviceProvider.GetRequiredService<MyOptions>();
return new StatsDConfiguration
{
Host = myOptions.StatsDHost
};
});
});

try
{
// Assert
var configuration = provider.GetRequiredService<StatsDConfiguration>();
configuration.ShouldNotBeNull();
configuration.Host.ShouldBe(options.StatsDHost);
configuration.Prefix.ShouldBeEmpty();

var source = provider.GetRequiredService<IEndPointSource>();
source.ShouldNotBeNull();

var transport = provider.GetRequiredService<IStatsDTransport>();
transport.ShouldNotBeNull();
transport.ShouldBeOfType<SocketTransport>();

var publisher = provider.GetRequiredService<IStatsDPublisher>();
publisher.ShouldNotBeNull();
publisher.ShouldBeOfType<StatsDPublisher>();
}
finally
{
if (provider is IDisposable disposable)
{
disposable.Dispose();
}
}
// Assert
var configuration = provider.GetRequiredService<StatsDConfiguration>();
configuration.ShouldNotBeNull();
configuration.Host.ShouldBe(options.StatsDHost);
configuration.Prefix.ShouldBeEmpty();

var source = provider.GetRequiredService<IEndPointSource>();
source.ShouldNotBeNull();

var transport = provider.GetRequiredService<IStatsDTransport>();
transport.ShouldNotBeNull();
transport.ShouldBeOfType<SocketTransport>();

var publisher = provider.GetRequiredService<IStatsDPublisher>();
publisher.ShouldNotBeNull();
publisher.ShouldBeOfType<StatsDPublisher>();
}

[Fact]
Expand All @@ -192,17 +158,19 @@ public static void RegisteringServicesDoesNotOverwriteExistingRegistrations()
var existingSource = Substitute.For<IEndPointSource>();
var existingTransport = Substitute.For<IStatsDTransport>();
var existingPublisher = Substitute.For<IStatsDPublisher>();
var existingPublisherWithTags = Substitute.For<IStatsDPublisherWithTags>();

var provider = Configure(services =>
{
services.AddSingleton(existingConfig);
services.AddSingleton(existingSource);
services.AddSingleton(existingTransport);
services.AddSingleton(existingPublisher);
using var provider = Configure(services =>
{
services.AddSingleton(existingConfig);
services.AddSingleton(existingSource);
services.AddSingleton(existingTransport);
services.AddSingleton(existingPublisher);
services.AddSingleton(existingPublisherWithTags);
// Act
services.AddStatsD();
});
// Act
services.AddStatsD();
});

// Assert
var configuration = provider.GetRequiredService<StatsDConfiguration>();
Expand All @@ -216,6 +184,9 @@ public static void RegisteringServicesDoesNotOverwriteExistingRegistrations()

var publisher = provider.GetRequiredService<IStatsDPublisher>();
publisher.ShouldBe(existingPublisher);

var publisherWithTags = provider.GetRequiredService<IStatsDPublisherWithTags>();
publisherWithTags.ShouldBe(existingPublisherWithTags);
}

[Fact]
Expand Down Expand Up @@ -251,13 +222,13 @@ public static void CanRegisterServicesWithCustomTransport()
// Arrange
string host = "localhost";

var provider = Configure(services =>
{
services.AddSingleton<IStatsDTransport, MyTransport>();
using var provider = Configure(services =>
{
services.AddSingleton<IStatsDTransport, MyTransport>();
// Act
services.AddStatsD(host);
});
// Act
services.AddStatsD(host);
});

// Assert
var configuration = provider.GetRequiredService<StatsDConfiguration>();
Expand All @@ -283,13 +254,13 @@ public static void CanRegisterServicesWithIPTransport()
// Arrange
string host = "127.0.0.1";

var provider = Configure(services =>
{
// Act
services.AddSingleton<IStatsDTransport>(
ctx => new SocketTransport(ctx.GetRequiredService<IEndPointSource>(), SocketProtocol.IP));
services.AddStatsD(host);
});
using var provider = Configure(services =>
{
// Act
services.AddSingleton<IStatsDTransport>(
ctx => new SocketTransport(ctx.GetRequiredService<IEndPointSource>(), SocketProtocol.IP));
services.AddStatsD(host);
});

// Assert
var configuration = provider.GetRequiredService<StatsDConfiguration>();
Expand Down

0 comments on commit c59f171

Please sign in to comment.