Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialize a singleton after configuring dependency injection, but before the first http request

I am using Azure Functions version 2.x. It has built-in support for dependency injection.

So I can register my service IMyService for DI at singleton scope using:

public class Startup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder builder)
    {
        builder.Services.AddSingleton<IOther, DefaultOther>();
        builder.Services.AddSingleton<IMyService, DefaultMyService>();  // IMyService depends on IOther.
    }
}

An instance of DefaultMyService is created the first time the function gets executed. This means the first request is slower because it does heavy initialization that happens inside DefaultMyService (it populates cache, etc.).

Question: Is there a way to have DefaultMyService created earlier than the first request?

A similar question was asked for asp.net core, and the answers there suggests a few solutions, but none of them works in the context of a function app:

Option 1: Create an instance of my service (initialization happens here), and then register the instance (instead of registering the type)

var foo = new Foo();
services.AddSingleton<IFoo>(foo);

This doesn't work because in my case IMyService depends on other services, which are not instantiated at the time when I am registering IMyService in the Configure method. It fails with an error that's described here.

Option 2: Other suggestion is to use overloaded Configure method:

public void Configure(IApplicationBuilder app, IFoo foo) 
{
    ...
}

This also doesn't work because in case of function app, the only configure method that gets executed is Configure(IFunctionsHostBuilder builder), and other overloads are not called.

like image 298
Turbo Avatar asked Oct 27 '25 08:10

Turbo


1 Answers

because it does heavy initialization that happens inside DefaultMyService

This is where the core of the problem lies. As Mark Seemann explained here, Injection constructors should do nothing more checking for null and storing incoming dependencies. Any time you do any I/O or invoke the class's dependencies inside the constructor, you'll get in trouble.

Your question seems similar to this q/a, and my advise would be the same: extract the initialization logic out of the constructor and either do the following:

  • Do the initialization before wiring the object graph and supply the DI configuration with an initialized object, or
  • Resolve and invoke an object graph directly after the registration phase, and before the first request, in such way that the data can be initialized.
like image 143
Steven Avatar answered Oct 28 '25 23:10

Steven



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!