0

I'm refactoring a block code and wanted to use constructor injection for my services. So far i get null exceptions for my services ( prob because i don't have a container yet). Anyone a idea how i implement this?

namespace RampantRobots_NextLvl
{
    class Program
    {
        private static IBoardService _boardService;
        private static IPlayerService _playerService;

        public Program(IBoardService boardService,IPlayerService playerService)
        {
            _boardService = boardService;
            _playerService = playerService;
        }

        static void Main(string[] args)
        {
            var player = _playerService.Create(1, 1);
            var board = _boardService.Create(5,10,3,3,player);

            _boardService.Draw(player, board);
            _boardService.MovePlayer(player, board);

            Console.ReadLine();
        }
    }
}
Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • 1
    You’d have to look into whatever injection system you’re using. But do note that static methods aren’t called by instance so there’s never an object created nor a constructor called. – Sami Kuhmonen Dec 23 '18 at 08:33
  • You might want to check https://stackoverflow.com/questions/21288/which-net-dependency-injection-frameworks-are-worth-looking-into for a list of containers. – Progman Dec 23 '18 at 08:33
  • 2
    Welcome to SO. Basically, since you have a console application and the entry point of this application is the `Main` method, the very first thing you should do at the beginning of this method is to set up the dependencies. Which DI framerwork you use ? – Christos Dec 23 '18 at 08:33
  • Does thisd help? [Dependency Injection In Console Application](https://social.technet.microsoft.com/wiki/contents/articles/35761.c-dependency-injection-in-console-application.aspx) – Phil Cooper Dec 23 '18 at 08:36

1 Answers1

1

Even without a container the code can still use Pure DI as described here

First off, it is better to make those explicit dependencies instance fields rather than static.

private readonly IBoardService _boardService;
private readonly IPlayerService _playerService;

the bulk of the desired functionality should be refactored into a method that will be invoked once the class has been initialized.

public void Invoke() {
    var player = _playerService.Create(1, 1);
    var board = _boardService.Create(5, 10, 3, 3, player);

    _boardService.Draw(player, board);
    _boardService.MovePlayer(player, board);

    //...
}

That leaves Main to act as the composition root, where all the dependencies are created and injected into the dependent class and the desired functionality invoked.

Full example

class Program {
    private readonly IBoardService _boardService;
    private readonly IPlayerService _playerService;

    public Program(IBoardService boardService, IPlayerService playerService) {
        _boardService = boardService;
        _playerService = playerService;
    }

    public void Invoke() {
        var player = _playerService.Create(1, 1);
        var board = _boardService.Create(5, 10, 3, 3, player);

        _boardService.Draw(player, board);
        _boardService.MovePlayer(player, board);

        //...
    }

    static void Main(string[] args) {
        //Assuming default implementations
        IBoardService boardService = new BoardService(); 
        IPlayerService playerService = new PlayerService();

        //Explicit dependency injection via constructor
        var program = new Program(boardService, playerService);

        //invoke desired functionality
        program.Invoke();

        Console.ReadLine();
    }
}

When a container is eventually introduced (if at all), only the composition root would need to be refatcored to register dependencies.

Nkosi
  • 235,767
  • 35
  • 427
  • 472