Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DI in .NET Core without ASP.NET Core

I'm looking to write a daemon process using .NET Core which will basically act much like a cron 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.
like image 633
gzak Avatar asked Mar 08 '17 04:03

gzak


People also ask

How does DI work in .NET Core?

ASP.NET Core supports the dependency injection (DI) software design pattern, which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies. For more information specific to dependency injection within MVC controllers, see Dependency injection into controllers in ASP.NET Core.

How do you implement DI?

The recommended way to implement DI is, you should use DI containers. If you compose an application without a DI CONTAINER, it is like a POOR MAN'S DI . If you want to implement DI within your ASP.NET MVC application using a DI container, please do refer to Dependency Injection in ASP.NET MVC using Unity IoC Container.

What is IoC container in .NET Core?

ASP.NET Core contains a built-in dependency injection mechanism. In the Startup. cs file, there is a method called ConfigureServices which registers all application services in the IServiceCollection parameter. The collection is managed by the Microsoft.


2 Answers

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.

like image 74
Joel Harkes Avatar answered Oct 07 '22 05:10

Joel Harkes


As of.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();
}
like image 20
DalSoft Avatar answered Oct 07 '22 04:10

DalSoft