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.
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With