在配置依赖项注入之后但在第一个http请求之前,初始化一个单例 [英] Initialize a singleton after configuring dependency injection, but before the first http request

查看:112
本文介绍了在配置依赖项注入之后但在第一个http请求之前,初始化一个单例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Azure Functions 2.x版本.它具有对依赖项注入的内置支持.

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

因此我可以使用以下方法在单例范围内为DI注册我的服务IMyService:

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.
    }
}

第一次执行该函数时,将创建一个DefaultMyService的实例.这意味着第一个请求的速度较慢,因为它会进行大量的初始化,而该初始化发生在DefaultMyService内部(填充缓存等).

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.).

问题:是否可以在第一个请求之前创建DefaultMyService?

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

asp.net请求了类似问题核心,那里的答案提出了一些解决方案,但是它们都不在功能应用程序的上下文中起作用:

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:

选项1:创建我的服务的实例(此处会进行初始化),然后注册该实例(而不是注册类型)

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);

这不起作用,因为在我的情况下,IMyService依赖于其他服务,这些服务在我在Configure方法中注册IMyService时未实例化.它失败,并显示错误,此处.

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.

选项2:其他建议是使用重载的Configure方法:

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

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

这也不起作用,因为在使用功能应用程序的情况下,唯一执行的配置方法是Configure(IFunctionsHostBuilder builder),并且不会调用其他重载.

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.

推荐答案

因为它完成了在DefaultMyService内部进行的大量初始化

because it does heavy initialization that happens inside DefaultMyService

这是问题的核心所在.正如马克·塞曼(Mark Seemann)在此处所解释的那样,注入构造函数应该不做任何检查null并存储传入的依赖项.每当您执行任何I/O或在构造函数内部 调用类的依赖项时,都会遇到麻烦.

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 into trouble.

您的问题似乎类似于此问题/a ,我的建议是相同的:从构造函数中提取初始化逻辑,然后执行以下操作:

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:

  • 在连接对象图之前进行初始化,并为DI配置提供已初始化的对象,或者
  • 在注册阶段之后和第一个请求之前,直接解析并调用对象图,以便可以初始化数据.

这篇关于在配置依赖项注入之后但在第一个http请求之前,初始化一个单例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆