Instantiating new objects in .NET Core that use dependency injection in their constructor without using new

Viewed 872

I've been trying to grasp the concept of Dependency Injection within .NET Core but have hit a problem. I think I'm missing the point somewhere along the line.

As an example, say I have a top level GameHandler class, then a Game class and a ScoreCard class.

My Game class has a dependency on the ScoreCard class and this needs to be registered as a transient service since each new game needs a new scorecard. I can achieve that by doing this...

public class Game
{
    private readonly IScoreCard _scoreCard;

    public Game(IScoreCard scoreCard)
    {
        _scoreCard = scoreCard;
    }
}

Then I register the service in startup.cs in the ConfigureServices method

services.AddTransient<IScoreCard, ScoreCard>();

This is all good, it's a simple one to one relationship where the Game class needs a single instance of the ScoreCard class.

My GameHandler class also has a dependency on the Game class. However, in this case, I want to potentially have multiple games, probably stored in a dictionary of some sort along with a key. And I don't know how many I'll need because it depends on who is playing at a particular time so I'd need to create new Game objects whenever I need them.

If I try and do this using new, like this

Game _newGame = new Game();

it obviously doesn't work because my Game constructor now has the DI ScoreCard stuff in there and that doesn't match. So how do I create new instances of Game using DI without using new?

1 Answers

At some point, you need a 'scope'. That scope is a level in your code where your instances are created. In some cases, the scope may be main, in message passing systems, each 'message' will have a new scope.

If your scope is 'every time a new game is created', then using whatever DI package you are using (I'm guessing it's the default net core one), then you need to call IServiceProvider.CreateScope(). After this point, any time you ask the service provider to give you a new Game(), it will return one based on how each class was registered.

With dependency injection, you should never call new, you need to ask the service provider to give you an instance of a type.

 IServiceProvider.GetService<YourType>();

IServiceProvider can be retrieved either when you create it (after registration, and building), or it can actually be injected into a constructor too.

Related