I'm trying to create a context for my redis database without using Entity Framework. My connection depends on a ConnectionMultiplexer
class, so for unit testing I'm trying to use dependency injection. I'm not sure how to create the using statement for my context without the ConnectionMultiplexer
parameter.
Am I doing dependency injection wrong? How can I restructure so I can use the "using" context correctly and have it resolve the dependency for me?
GameSession.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using StackExchange.Redis;
namespace Bored.GameService.GameSession
{
public class GameSessionContext : IGameSession, IDisposable
{
private IDatabase conn;
private readonly IConnectionMultiplexer _muxer;
public GameSessionContext(IConnectionMultiplexer muxer)
{
_muxer = muxer;
string connectionString = Startup.Configuration.GetConnectionString("redis");
_muxer = ConnectionMultiplexer.Connect(connectionString);
//conn = muxer.GetDatabase();
//conn.StringSet("foo", "bar");
//var value = conn.StringGet("foo");
//Console.WriteLine(value);
}
public void GetGameState()
{
throw new NotImplementedException();
}
public void AddGameState()
{
throw new NotImplementedException();
}
public void Dispose()
{
_muxer.Dispose();
}
}
}
Here is where I'm registering the dependency in my startup.cs
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IConnectionMultiplexer, ConnectionMultiplexer>();
services.AddSignalR();
services.AddCors(options =>
{
options.AddPolicy("ClientPermission", policy =>
{
policy.AllowAnyHeader()
.AllowAnyMethod()
.WithOrigins("http://localhost:3000")
.AllowCredentials();
});
});
}
Here is how I'm using it in my GameServiceAPI class:
using Bored.GameService.Clients;
using Bored.GameService.GameSession;
using Bored.GameService.Models;
using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;
namespace Bored.GameService.GameServiceAPI
{
public class GameServiceHub : Hub<IGameClient>
{
public Task SendMessage(GameMessage message)
{
// Throws an error because GameSessionContext has no IConnectionMultiplexer parameter passed in.
using (var context = new GameSessionContext())
{
// var gameState = context.GetGameState(context);
// context.AddGameState(gameState);
// Clients.All.ReceiveMessage(gameState);
}
return Clients.All.ReceiveMessage(message);
}
}
}
Thanks to @DavidBrowne's suggestion for registering both the GameServiceHub and GameSessionContext with DI.
Here's the code I used to get this to work:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IConnectionMultiplexer>(ConnectionMultiplexer.Connect(Configuration.GetConnectionString("redis")));
services.AddScoped<IGameSessionContext, GameSessionContext>();
services.AddSignalR();
services.AddCors(options =>
{
options.AddPolicy("ClientPermission", policy =>
{
policy.AllowAnyHeader()
.AllowAnyMethod()
.WithOrigins("http://localhost:3000")
.AllowCredentials();
});
});
GameSessionContext.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using StackExchange.Redis;
namespace Bored.GameService.GameSession
{
public class GameSessionContext : IGameSessionContext
{
private IDatabase conn;
private readonly IConnectionMultiplexer _muxer;
public GameSessionContext(IConnectionMultiplexer muxer)
{
_muxer = muxer;
}
public string GetGameState()
{
conn = _muxer.GetDatabase();
conn.StringSet("foo", "Here's game state");
return conn.StringGet("foo");
}
public void AddGameState()
{
throw new NotImplementedException();
}
}
}
GameServiceHub.cs
using Bored.GameService.Clients;
using Bored.GameService.GameSession;
using Bored.GameService.Models;
using Microsoft.AspNetCore.SignalR;
using System;
using System.Threading.Tasks;
namespace Bored.GameService.GameServiceAPI
{
public class GameServiceHub : Hub<IGameClient>
{
private IGameSessionContext _context;
public GameServiceHub(IGameSessionContext context)
{
_context = context;
}
public Task SendMessage(GameMessage message)
{
var state = _context.GetGameState();
Console.WriteLine(state);
// var gameState = context.GetGameState(context);
// context.AddGameState(gameState);
return Clients.All.ReceiveMessage(message);
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.