Injecting scoped service in a singleton service

If you want to use a scoped service in a singleton service in a Asp.Net Core MVC project you can’t inject it via constructor injection. You’ll have to create a scope when needed. In my case I needed to use a DbContext service regisered with .AddDbContext as a scoped service in startup.cs into a hosted service.

First you have to create a service inheriting of IHostedService (Microsoft.Extensions.Hosting) with the following code:


public abstract class HostedService : IHostedService
{
// Example untested base class code kindly provided by David Fowler: https://gist.github.com/davidfowl/a7dd5064d9dcf35b6eae1a7953d615e3

private Task _executingTask;
private CancellationTokenSource _cts;

public Task StartAsync(CancellationToken cancellationToken)
{
// Create a linked token so we can trigger cancellation outside of this token's cancellation
_cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

// Store the task we're executing
_executingTask = ExecuteAsync(_cts.Token);

// If the task is completed then return it, otherwise it's running
return _executingTask.IsCompleted ? _executingTask : Task.CompletedTask;
}

public async Task StopAsync(CancellationToken cancellationToken)
{
// Stop called without start
if (_executingTask == null)
{
return;
}

// Signal cancellation to the executing method
_cts.Cancel();

// Wait until the task completes or the stop token triggers
await Task.WhenAny(_executingTask, Task.Delay(-1, cancellationToken));

// Throw if cancellation triggered
cancellationToken.ThrowIfCancellationRequested();
}

// Derived classes should override this and execute a long running method until
// cancellation is requested
protected abstract Task ExecuteAsync(CancellationToken cancellationToken);
}

The following code in the singleton service works for me:

public class AnyService
{
    private readonly IServiceScopeFactory _scopeFactory;

    public AnyService(IServiceScopeFactory scopeFactory)
    {
        _scopeFactory = scopeFactory;
    }

    public void Execute()
    {
        using (var scope = _scopeFactory.CreateScope())
        {
            var dbContext = scope.ServiceProvider.GetRequiredService<MyDbContext>();
            
        }
    }
    
}

Getting started with Blazor

Blazor – Microsoft’s new web technology. I read a lot about the new possibilities and decided to get started with Blazor. My first step was visiting https://docs.microsoft.com/de-de/aspnet/core/blazor/get-started?view=aspnetcore-3.0&tabs=visual-studio to get all information about how to install Blazor and how to programm my first code example. I downloaded the latest version of the .net Core SDK v3.0.0-preview9 from https://dotnet.microsoft.com/download/dotnet-core/3.0 and installed the Blazor templates by command shell.

dotnet new -i Microsoft.AspNetCore.Blazor.Templates::3.0.0-preview9.19424.4

Now I wanted to create a new project and select Blazor as template. But there were no .net core 3 templates in the selection only core 2.1 and 2.2 project templates. Afterwords I tried many things to get it working but nothing helped.

Solution: I should have read the instructions in a better and more sensible way. I missed an important detail: The latest .net Core 3 preview version only works with the latest Visual Studio preview version.

.net Core SDK download page
.net Core SDK download page

My installed version of Visual Studio was Community Edition 16.2.5. No chance to run the latest SDK version. I had to deinstall SDK 3 preview 9 and installed v3.0.0-preview6 because this SDK version supports Visual Studio 2019 v16.2.

Coming back to Visual Studio and creating a new project I could choose from .net Core 3 templates as expected.