question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Q: Best practice MediatR in a console application?

See original GitHub issue

Hello,

It is my understanding that it is not straight forward to go from ASP.NET Core to a Console application as ASP.NET Core handles the scope creation, for example, to use a DbContext in MediatR. I have read about MediatR and Dependency Injection in .NET Core and I am trying to figure out how to properly implement the following in a console application. “A small menu and a request to MediatR for every option to execute queries in a DbContext.”

Here is what I have working for now. I am just wondering if it is considered best practices or if there is a better way to do it?

Program.cs

public static class Program
{
    public static async Task Main(string[] args)
    {
        var hostBuilder = CreateHostBuilder(args);

        await hostBuilder.RunConsoleAsync();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureServices((hostingContext, services) =>
            {
                services.AddDbContext<MyDbContext>(options =>
                    options.UseSqlServer(configuration.GetConnectionString("MyDatabase")));

                services.AddScoped<IMyDbContext>(provider => provider.GetService<MyDbContext>());
                services.AddMediatR(Assembly.GetExecutingAssembly());
                services.AddSingleton<IHostedService, ConsoleApp>();
            });
}

ConsoleApp.cs

public class ConsoleApp : IHostedService
{
    private readonly ILogger _logger;
    private readonly IServiceScopeFactory _serviceScopeFactory;
    public ConsoleApp(ILogger<ConsoleApp> logger, IServiceScopeFactory serviceScopeFactory)
    {
        _logger = logger;
        _serviceScopeFactory = serviceScopeFactory;
    }
    
    public async Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Starting application");
        int choice = -1;
        while (choice != 0)
        {
            WriteLine("Please choose one of the following options:");
            WriteLine("0. Exit");
            WriteLine("1. Extract receipts");
            WriteLine("2. Upload receipts");

            try
            {
                choice = int.Parse(ReadLine());
            }
            catch (FormatException)
            {
                choice = -1;
            }

            switch (choice)
            {
                case 0:
                    WriteLine("Bye...");
                    break;
                case 1:
                    using (var scope = _serviceScopeFactory.CreateScope())
                    {
                        var _mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
                       
                        await _mediator.Send(new ExtractReceiptsCommand(), cancellationToken);
                    }
                    break;
                case 2:
                    using (var scope = _serviceScopeFactory.CreateScope())
                    {
                        var _mediator = scope.ServiceProvider.GetRequiredService<IMediator>();

                        await _mediator.Send(new UploadReceiptsCommand(), cancellationToken);
                    }
                    break;
                default:
                    WriteLine("Invalid choice! Please try again.");
                    break;
            }
        }
    }
}

Then I inject IMyDbContext inside the request handler constructor and everything looks like it is working properly. Thank you for your suggestions.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
lilasquaredcommented, Jan 22, 2020

MediatR shouldn’t care whether you’re in a web context or a console context so long as the DI is all hooked up which it looks like you have done here.

0reactions
Pyrobolsercommented, Jan 22, 2020

@lilasquared That’s exactly what I’m trying to do.

@jbogard I’ll try to look into it, let me know if you know of an example that lies somewhere that I could look at. If you happen to add some details about Console app I’ll be sure to check it out too.

Thank you both for your help.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Using MediatR in a console application
Does anyone know how to implement MediatR in a console application, to call a handler function using the _mediatr.Send(obj) syntax.
Read more >
Clean Message Bus Consumers with MediatR in .NET
Enroll to "Cloud Fundamentals: AWS Services for C# Developers" for FREE: https://bit.ly/3XKUBOH Get the source code: ...
Read more >
CQRS and MediatR in ASP.NET Core
You can think of MediatR as an “in-process” Mediator implementation, that helps us build CQRS systems. All communication between the user ...
Read more >
Dealing with Duplication in MediatR Handlers
When it comes to building apps using CQRS and MediatR, we remove these layer types (Service and Repository) in favor of request/response pairs ......
Read more >
How to implement CQRS with MediatR - Part 1
This post is about implementing mediator pattern in a dotnet console application using MediatR library.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found