@@ -311,6 +311,109 @@ let main argv =
311311 |> Async.RunSynchronously
312312```
313313
314+ ### Passing Dependencies to Commands
315+
316+ This real-life example for running database migrations demonstrates the following features:
317+ * Uses Microsoft.Extensions.Hosting.
318+ * Passes the ` ILogger ` to the commands.
319+ * Uses async/task commands.
320+ * Shows help if no command is passed.
321+
322+ ``` F#
323+ module Program
324+
325+ open EvolveDb
326+ open System.Data.SqlClient
327+ open System.IO
328+ open Microsoft.Extensions.Hosting
329+ open Microsoft.Extensions.Configuration
330+ open Microsoft.Extensions.DependencyInjection
331+ open Serilog
332+ open EvolveDb.Configuration
333+ open FSharp.SystemCommandLine
334+ open System.CommandLine.Invocation
335+ open System.CommandLine.Help
336+
337+ let buildHost (argv: string[]) =
338+ Host.CreateDefaultBuilder(argv)
339+ .ConfigureHostConfiguration(fun configHost ->
340+ configHost.SetBasePath(Directory.GetCurrentDirectory()) |> ignore
341+ configHost.AddJsonFile("appsettings.json", optional = false) |> ignore
342+ )
343+ .UseSerilog(fun hostingContext configureLogger ->
344+ configureLogger
345+ .MinimumLevel.Information()
346+ .Enrich.FromLogContext()
347+ .WriteTo.Console()
348+ .WriteTo.File(
349+ path = "logs/log.txt",
350+ rollingInterval = RollingInterval.Year
351+ )
352+ |> ignore
353+ )
354+ .Build()
355+
356+ let repairCmd (logger: ILogger) =
357+ let handler (env: string) =
358+ task {
359+ logger.Information($"Environment: {env}")
360+ logger.Information("Starting EvolveDb Repair (correcting checksums).")
361+ let! connStr = KeyVault.getConnectionString env
362+ use conn = new SqlConnection(connStr)
363+ let evolve = Evolve(conn, fun msg -> printfn "%s" msg)
364+ evolve.TransactionMode <- TransactionKind.CommitAll
365+ evolve.Locations <- [| "Scripts" |]
366+ evolve.IsEraseDisabled <- true
367+ evolve.MetadataTableName <- "_EvolveChangelog"
368+ evolve.Repair()
369+ }
370+
371+ command "repair" {
372+ description "Corrects checksums in the database."
373+ inputs (Input.Argument<string>("env", "The keyvault environment: [dev, beta, prod]."))
374+ setHandler handler
375+ }
376+
377+ let migrateCmd (logger: ILogger) =
378+ let handler (env: string) =
379+ task {
380+ logger.Information($"Environment: {env}")
381+ logger.Information("Starting EvolveDb Migrate.")
382+ let! connStr = KeyVault.getConnectionString env
383+ use conn = new SqlConnection(connStr)
384+ let evolve = Evolve(conn, fun msg -> printfn "%s" msg)
385+ evolve.TransactionMode <- TransactionKind.CommitAll
386+ evolve.Locations <- [| "Scripts" |]
387+ evolve.IsEraseDisabled <- true
388+ evolve.MetadataTableName <- "_EvolveChangelog"
389+ evolve.Migrate()
390+ }
391+
392+ command "migrate" {
393+ description "Migrates the database."
394+ inputs (Input.Argument<string>("env", "The keyvault environment: [dev, beta, prod]."))
395+ setHandler handler
396+ }
397+
398+ let showHelp (ctx: InvocationContext) =
399+ let hc = HelpContext(ctx.HelpBuilder, ctx.Parser.Configuration.RootCommand, System.Console.Out)
400+ ctx.HelpBuilder.Write(hc)
401+
402+ [<EntryPoint>]
403+ let main argv =
404+ let host = buildHost argv
405+ let logger = host.Services.GetService<ILogger>()
406+
407+ rootCommand argv {
408+ description "Database Migrations"
409+ inputs (Input.Context())
410+ setHandler (showHelp)
411+ addCommand (repairCmd logger)
412+ addCommand (migrateCmd logger)
413+ }
414+
415+ ```
416+
314417### Creating a Root Command Parser
315418
316419If you want to manually invoke your root command, use the ` rootCommandParser ` CE (because the ` rootCommand ` CE is auto-executing).
0 commit comments