I want to create a simple game and use one of IoC containers. Every game has players, so I want to inject them into Game
class. The thing is, there could be different types of players. First player will be always Human (device owner;)), but his opponent: Human (play and pass), Bot or Online (human, but playing through internet).
Here is the code. There different players:
public class Human : IPlayer
{
public int Id { get; set; }
public string Name { get; set; }
public PlayerType Type { get; set; }
}
public class Bot : Human
{
}
public class OnlinePlayer : Human
{
}
public interface IPlayer
{
int Id { get; set; }
string Name { get; set; }
PlayerType Type { get; set; }
}
and Game
class:
public class Game : IGame
{
public GameType Type { get; private set; }
public List<IPlayer> Players { get; private set; }
public Game(GameType type, List<IPlayer> players)
{
Type = type;
Players = players;
}
}
public interface IGame
{
GameType Type { get; }
List<IPlayer> Players { get; }
}
As you can see, I inject List of players in Game's container. Here is my question:
How can I resolve List<IPlayer>
in case of differen type GameType
?
if GameType = Single player -> Inject Human and Bot
if GameType = Pass and play -> Inject Human and Human
if GameType = Online game -> Inject Human and OnlinePlayer
There's no reason to make it more complicated than it has to be. You can put something like this in an Abstract Factory :
if (gameType == GameType.Single)
return new Game(
GameType.Single,
new List<IPlayer> { CreateHuman(); CreateBot() });
else if (gameType == GameType.PassAndPlay)
return new Game(
GameType.PassAndPlay,
new List<IPlayer> { CreateHuman(); CreateHuman() });
else
return new Game(
GameType.Online,
new List<IPlayer> { CreateHuman(); CreateOnlinePlayer() });
You can use Ninject for this, i use this approach in some projects that i worked, and is very simple, see the Ninject project site: https://github.com/ninject/Ninject/wiki/Contextual-Binding
About your comment my suggest is separe the games types in concrete classes that implements IGame
interface`, see the example:
public interface IGame
{
GameType Type { get; }
ReadOnlyCollection<IPlayer> Players { get; }
}
public class GameSingle : IGame
{
public GameSingle(List<IPlayer> players)
{
Players = players.AsReadOnly();
}
public GameType Type => GameType.Single;
public ReadOnlyCollection<IPlayer> Players { get; }
}
public class GameOnline : IGame
{
public GameOnline(List<IPlayer> players)
{
Players = players.AsReadOnly();
}
public GameType Type => GameType.Online;
public ReadOnlyCollection<IPlayer> Players { get; }
}
public class GamePlayAndPass : IGame
{
public GamePlayAndPass(List<IPlayer> players)
{
Players = players.AsReadOnly();
}
public GameType Type => GameType.PassAndPlay;
public ReadOnlyCollection<IPlayer> Players { get; }
}
Now in the module of the ninject :
Kernel.Bind<IPlayer>().To<Bott>().WhenInjectedExactlyInto<GameSingle>();
Kernel.Bind<IPlayer>().To<OnlinePlayer>().WhenInjectedExactlyInto<GameOnline>();
Kernel.Bind<IPlayer>().To<Human>().WhenInjectedExactlyInto<GamePlayAndPass>();
Kernel.Bind<IPlayer>().To<Human>();
And then you just need to define when and where inject the IGame concrete class XD.
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.