DI in .NET Core without ASP.NET Core

2019-06-21 08:07发布

问题:

I'm looking to write a daemon process using .NET Core which will basically act much like a chron job and just orchestrate API/DB calls on some interval. As such, it has no need to expose any web routes, so there's no need for ASP.NET Core.

However, afaik ASP.NET Core is where you get that nice Startup class with all the DI plumbing and environment-based configuration you might need.

The way I see it, I have two options:

  1. Forgo ASP.NET Core and just hook up the DI framework on my own. If I go that route, how do I do that?
  2. Include ASP.NET Core just for the DI portion, but then how do I spawn background tasks which "run forever" outside of any request context? My understanding is that the DI framework very much assumes there's some sort of incoming request to orchestrate all the injections.

回答1:

You seem to pose multiple questions let me try to answer them one by one.

Dependendency injection without Startup Class.

This is definitely possible. Since the Startup class is part of the WebHostBuilder package (which contains Kestrel/webserver). The Dependency injection is nuget package is just a dependency on this package and so can be used alone in the following way:

var services = new ServiceCollection();
services.AddTransient<IMyInterface, MyClass>();
var serviceProvider = services.BuildServiceProvider(); //ioc container
serviceProvider.GetService<IMyInterface>();

So at your program main (startup function) you can add this code and maybe even make the ServiceProvider Staticaly available.

Note that the IHostingEnvironment is also part of the kestrel package and not available to you, but there are simple workarounds for this.

Registration

Im not sure what exactly you mean by spawning background tasks/running forever. But in dotnet you can spawn tasks with TaskCreationOptions.LongRunning to tell the schedular that your task will be running very long and dotnet wel optimise threads for this. you can also use serviceProvider in these tasks.

The only downside to the DI is that you need to set it up at the startup of your application and cannot add new services while running your application (actually you can add to services and then rebuild the serviceProvider, but its easier using another external IOC container). If you where thinking of running some kind of plugin system where dependencies would automaticaly be registered, you're better of making your own factory method.

Also note when using plugins, when they are loaded in as dll's, they cannot be unloaded so if you have a theoretically unlimited amount of plugins, your memory will slowly build up every time you add new plugins.



回答2:

Update in .NET Core 2.1 this can/should be done with a Generic Host. From .NET Core docs:

"The goal of the Generic Host is to decouple the HTTP pipeline from the Web Host API to enable a wider array of host scenarios..."

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-2.1

public static async Task Main(string[] args)
{
  var builder = new HostBuilder()
    .ConfigureAppConfiguration((hostingContext, config) =>

    .ConfigureServices((hostContext, services) =>
    {
       // ...
    });

  await builder.RunConsoleAsync();
}