lundi 3 janvier 2022

How to avoid passing around runtime parameter everywhere

I have a client app that let's user take part in a match. In almost all cases, maybe except tests, user takes part in one or zero matches at the same time. Every match have a unique ID, let's call it MatchID. I have many services that provides information about the match, e.g.:

interface IMatchPlayersRepository
{
    string[] GetMatchPlayers(string matchId);
    string GetBestPlayer(string matchId);
}

interface IMatchFieldsInfo
{
    int GetFieldSize(string matchId);
}

interface IMatchScoreboardProvider
{
    Scoreboard GetScoreboard(string matchId, string someOtherParam);
}

// And many others...

Implementations of those use one another, e.g.:

public class MatchScoreboardProvider : IMatchScoreboardProvider
{
    public MatchScoreboardProvider(IMatchPlayersRepository playersRepository)
    { //...
    }

    public Scoreboard GetScoreboard(string matchId, string someOtherParam)
    {
        var bestPlayer = _playersRepository.GetBestPlayer(matchId);
        //...
    }
}

How do I prevent passing matchId everywhere? Using factories only moves the problem to factory methods, e.g.:

public class MatchPlayersRepositoryFactory
{
    public IMatchPlayersRepository Get(string matchId) => new MatchPlayersRepository(matchId);
}

public class MatchScoreboardProvider : IMatchScoreboardProvider
{
    // Created from factory
    public MatchScoreboardProvider(string matchId, MatchPlayersRepositoryFactory playersRepositoryFactory)
    { //...
    }

    public Scoreboard GetScoreboard(string someOtherParam)
    {
        var bestPlayer = _playersRepositoryFactory.Get(_matchId).GetBestPlayer();
        //...
    }
}

Ideally, I would have another DI "composition root" for every match, where all object are created from this new DI framework, that passes matchId to them. However, creating a new "composition root" seems like a really bad idea, from what I understand.

Aucun commentaire:

Enregistrer un commentaire