Appearance
Using IoC Services
Very frequently, folks have wanted to either use services from their IoC/DI container for their application, or to have Oakton resolve the command objects from the application's DI container. New in Oakton 6.2 is that very ability.
Injecting Services into Commands
If you are using Oakton's IHost integration, you can write commands that use IoC services by simply decorating a publicly settable property on your Oakton command classes with the new [InjectService]
attribute.
First though, just to make sure you're clear about when and when this isn't applicable, this applies to Oakton used from an IHostBuilder
or ApplicationBuilder
like so:
cs
public class Program
{
public static Task<int> Main(string[] args)
{
return CreateHostBuilder(args)
.RunOaktonCommands(args);
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
// This is a little old-fashioned, but still valid .NET core code:
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) => { services.AddHostedService<Worker>(); });
}
Then you can decorate your command types something like this:
cs
public class MyDbCommand : OaktonAsyncCommand<MyInput>
{
[InjectService]
public MyDbContext DbContext { get; set; }
public override Task<bool> Execute(MyInput input)
{
// do stuff with DbContext from up above
return Task.FromResult(true);
}
}
Just know that when you do this and execute a command that has decorated properties for services, Oakton is:
- Building your system's
IHost
- Creating a new
IServiceScope
from your application's DI container, or in other words, a scoped container - Building your command object and setting all the dependencies on your command object by resolving each dependency from the scoped container created in the previous step
- Executing the command as normal
- Disposing the scoped container and the
IHost
, effectively in atry/finally
so that Oakton is always cleaning up after the application
Using IoC Command Creators
If you would like to just always have Oakton try to use dependency injection in the constructor of the command classes, you also have this option. First, register Oakton through the application's DI container and run the Oakton commands through the IHost.RunHostedOaktonCommands()
extension method as shown below: