From 0b41e9aa07a228e510aae21989e1eb87b56f0cb4 Mon Sep 17 00:00:00 2001 From: Mayuki Sawatari Date: Mon, 22 May 2023 16:59:01 +0900 Subject: [PATCH] Support constructor injection with IConnectionMultiplexerFactory --- .../MessagePipeRedisOptions.cs | 4 +- .../ServiceCollectionRedisExtensions.cs | 21 +++++- .../ConnectionMultiplexerFactoryTest.cs | 69 +++++++++++++++++++ 3 files changed, 89 insertions(+), 5 deletions(-) create mode 100644 tests/MessagePipe.Redis.Tests/ConnectionMultiplexerFactoryTest.cs diff --git a/src/MessagePipe.Redis/MessagePipeRedisOptions.cs b/src/MessagePipe.Redis/MessagePipeRedisOptions.cs index 34d56e9..59542cb 100644 --- a/src/MessagePipe.Redis/MessagePipeRedisOptions.cs +++ b/src/MessagePipe.Redis/MessagePipeRedisOptions.cs @@ -15,13 +15,11 @@ public interface IConnectionMultiplexerFactory public sealed class MessagePipeRedisOptions { - public IConnectionMultiplexerFactory ConnectionMultiplexerFactory { get; } public IRedisSerializer RedisSerializer { get; set; } - public MessagePipeRedisOptions(IConnectionMultiplexerFactory connectionMultiplexerFactory) + public MessagePipeRedisOptions() { this.RedisSerializer = new MessagePackRedisSerializer(); - this.ConnectionMultiplexerFactory = connectionMultiplexerFactory; } } } \ No newline at end of file diff --git a/src/MessagePipe.Redis/ServiceCollectionRedisExtensions.cs b/src/MessagePipe.Redis/ServiceCollectionRedisExtensions.cs index c6d5a0e..0a56e3c 100644 --- a/src/MessagePipe.Redis/ServiceCollectionRedisExtensions.cs +++ b/src/MessagePipe.Redis/ServiceCollectionRedisExtensions.cs @@ -20,6 +20,18 @@ public static IServiceCollection AddMessagePipeRedis(this IServiceCollection ser return AddMessagePipeRedis(services, connectionMultiplexerFactory, _ => { }); } + public static IServiceCollection AddMessagePipeRedis(this IServiceCollection services) + where T : class, IConnectionMultiplexerFactory + { + return AddMessagePipeRedis(services, _ => { }); + } + + public static IServiceCollection AddMessagePipeRedis(this IServiceCollection services, Action configure) + where T : class, IConnectionMultiplexerFactory + { + return AddMessagePipeRedis(services, ServiceDescriptor.Singleton(), configure); + } + public static IServiceCollection AddMessagePipeRedis(this IServiceCollection services, IConnectionMultiplexer connectionMultiplexer, Action configure) { return AddMessagePipeRedis(services, new SingleConnectionMultiplexerFactory(connectionMultiplexer), configure); @@ -27,10 +39,15 @@ public static IServiceCollection AddMessagePipeRedis(this IServiceCollection ser public static IServiceCollection AddMessagePipeRedis(this IServiceCollection services, IConnectionMultiplexerFactory connectionMultiplexerFactory, Action configure) { - var options = new MessagePipeRedisOptions(connectionMultiplexerFactory); + return AddMessagePipeRedis(services, ServiceDescriptor.Singleton(connectionMultiplexerFactory), configure); + } + + static IServiceCollection AddMessagePipeRedis(IServiceCollection services, ServiceDescriptor connectionMultiplexerServiceDesc, Action configure) + { + var options = new MessagePipeRedisOptions(); configure(options); services.AddSingleton(options); // add as singleton instance - services.AddSingleton(options.ConnectionMultiplexerFactory); + services.Add(connectionMultiplexerServiceDesc); services.AddSingleton(options.RedisSerializer); services.Add(typeof(IDistributedPublisher<,>), typeof(RedisPublisher<,>), InstanceLifetime.Singleton); diff --git a/tests/MessagePipe.Redis.Tests/ConnectionMultiplexerFactoryTest.cs b/tests/MessagePipe.Redis.Tests/ConnectionMultiplexerFactoryTest.cs new file mode 100644 index 0000000..3c09648 --- /dev/null +++ b/tests/MessagePipe.Redis.Tests/ConnectionMultiplexerFactoryTest.cs @@ -0,0 +1,69 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using FluentAssertions; +using MessagePipe.Tests; +using Microsoft.Extensions.DependencyInjection; +using StackExchange.Redis; +using Xunit; + +namespace MessagePipe.Redis.Tests; + +public class ConnectionMultiplexerFactoryTest +{ + [Fact] + public async Task CreateFromInstance() + { + var connection = TestHelper.GetLocalConnectionMultiplexer(); + var services = new ServiceCollection(); + services.AddMessagePipe(); + services.AddMessagePipeRedis(connection); + var sp = services.BuildServiceProvider(); + + var publisher = sp.GetRequiredService>(); + var subscriber = sp.GetRequiredService>(); + + var results = new List(); + await using var _ = await subscriber.SubscribeAsync("Foo", x => results.Add(x)); + + await publisher.PublishAsync("Foo", "Bar"); + await Task.Delay(250); + results.FirstOrDefault().Should().Be("Bar"); + } + + [Fact] + public async Task CreateFromGenericType() + { + var connection = TestHelper.GetLocalConnectionMultiplexer(); + var services = new ServiceCollection(); + services.AddSingleton(connection); + services.AddMessagePipe(); + services.AddMessagePipeRedis(); + var sp = services.BuildServiceProvider(); + + var publisher = sp.GetRequiredService>(); + var subscriber = sp.GetRequiredService>(); + + var results = new List(); + await using var _ = await subscriber.SubscribeAsync("Foo", x => results.Add(x)); + + await publisher.PublishAsync("Foo", "Bar"); + await Task.Delay(250); + results.FirstOrDefault().Should().Be("Bar"); + } + + public class TestConnectionMultiplexerFactory : IConnectionMultiplexerFactory + { + readonly IConnectionMultiplexer connectionMultiplexer; + + public TestConnectionMultiplexerFactory(IConnectionMultiplexer connectionMultiplexer) + { + this.connectionMultiplexer = connectionMultiplexer; + } + + public IConnectionMultiplexer GetConnectionMultiplexer(TKey key) + { + return connectionMultiplexer; + } + } +} \ No newline at end of file