Dependency Injection in Console Apps (C#)

Dependency Injection in Console Apps (C#)

James Charlesworth

By James Charlesworth

7 August 20182 min read

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