1

I am struggling to determine if this is the correct method for injecting dependencies from my Console Application Main method into my primary application class instance.

I have the following code:

Program Class

static void Main(string[] args)
{
    var container = new SimpleInjector.Container();

    // Registrations here.
    container.Register<ILogger, FileLogger>();

    //Verify the container.
    container.Verify();

    ILogger log = container.GetInstance<ILogger>();

    log.Info("Logging From Main Method");

    //Start Main Agent
    MainAgent agent = new MainAgent(log);
    agent.Start();
}

Main Agent Class

public class MainAgent
{
    private ILogger log;

    public MainAgent(ILogger _log)
    {
        log = _log;
    }

    public void Start()
    {
        //Main Application Code here.
        Console.WriteLine("main Agent Started.");
        log.Info("Logging through logger in MainAgent Class");
        Console.ReadLine();
    }
}

I come from a background of writing DotNetCore applications in ASP.Net Core, so I am used to how the DI works with that, registering a service into the pipeline, and them all being available for me to cherry pick in each controller's Constructor.

My worry is I may have 20-30 services, all of which will all need to be injected in as parameters each time I “New Up” a new instance of a class for them to be avaliable to the constructor in my new class.

Am I missing some magical feature which will just make all my registered services available in any newly initialized constructor for me to reference as I do with ASP.Net Core?

tornup
  • 263
  • 1
  • 4
  • 15
  • 1
    You shouldn't instantiate classes like MainAgent yourself. Your container should do that. And it needs to use reflection to see what interfaces are needed and make instances of the interfaces needed. Typically when you instantiate your top class, your container will need to create a whole tree of instances to be able to satisfy the needs of the constructors in your whole application tree. – Hans Kilian Jan 17 '18 at 13:40

2 Answers2

3

No, there is no magic.

What you are missing is that AspNetCore automatically resolves your controller under the covers, which resolves the entire object graph of dependencies that controller has (that is, any dependencies of the controller, dependencies of those dependencies, etc.)

Similarly, in a console app, you need to resolve the entire object graph (usually at startup).

static void Main(string[] args)
{
    // Begin Composition Root

    var container = new SimpleInjector.Container();

    // Registrations here.
    container.Register<ILogger, FileLogger>();
    container.Register<IMainAgent, MainAgent>();

    //Verify the container.
    container.Verify();

    // End Composition Root

    MainAgent agent = container.GetInstance<IMainAgent>();

    //Start Main Agent
    agent.Start();
}

Effectively the "agent" is should be considered to be the entire application. The console is just a shell to set everything in motion. Do note that it would probably be sensible in most situations to pass in the args from the console app, so they can be parsed and responded to by the "agent" as appropriate.

agent.Start(args);    
NightOwl888
  • 55,572
  • 24
  • 139
  • 212
0
Am I missing some magical feature which will just make  all my registered services available in any

Simple answer yes you are SimpleInjector supports direct object creation

var agent = container.GetInstance<MainAgent>();

With out the need to register the instance at all. You can make an interface and then register like you do ILogger but making the method virtual and using directly the class name is also fine. You can read more on the subject here

Filip Cordas
  • 2,531
  • 1
  • 12
  • 23