Dependency Injection in Console Apps (C#)

Smart argument binding and DI in .NET Core Console Apps

Dependency Injection in Console Apps (C#)

I recently wrote a library for binding command line arguments to class functions in .NET Core. This came about from a need to make a console app that I could use to easily run code from a .NET Core web api solution. For example, I had a lot of code written in neat little "command" classes like the one below

public class SendEmailCommand
{
    private readonly IEmailService _service; 

    // inject a service class that can perform the actual sending
    // (eg. SendGrid/Mailchimp client)
    public SendEmailCommand(IEmailService service)
    {
        _service = service; 
    }

    // Invokes this command to send an email
    public async Task Invoke(string address, string content = "Empty")
    {
        if (address == null)
            throw new ArgumentNullException(nameof(address));

        // Build the email
        var email = new Email { Address = address, Content = content };

        // Send the email using the injected service
        await _service.Send(email);
    }
}

This was being called from an api controller like this

public class EmailsController : Controller
{
    private readonly SendEmailCommand _command;

    public EmailsController(SendEmailCommand command)
    {
        _command = command;
    }

    [HttpPost]
    public async Task<IActionResult> Send(string address, string content)
    {
        await _command.Invoke(address, content);
        return Accepted();
    }
}

Now it's not too difficult to just create an instance of SendEmailCommand in a .NET console app and call it, but what I was really looking for was a way to automagically bind the address and content parameters. In .NET WebApi the arguments are automatically bound from the query string or request bodies for you, and I wanted to approximate that.

The closest I could find was Microsoft's Microsoft.Extensions.CommandLineUtils package but this doesn't seem to be actively maintained any more and it has rather clunky syntax.

So I created an extension to this package, subclassing the CommandLineApplication class and adding dependency injection and parameter binding support

Check it out on GitHub here: https://github.com/jcharlesworthuk/CommandLineInjector

    James Charlesworth

    Hi, I'm James

    I've worked in software development for nearly 20 years, from junior engineer to Director of Engineering. I'm here to help you get your foot on the next rung of your career ladder. I post weekly videos on YouTube and publish guides, articles, and guided project tutorials on this site. Sign up to my newsletter too for monthly career tips and insights in the world of software development.

    Related Project Tutorials

    Read Next...