【问题标题】:Why is scoped service instantiated multiple times?为什么作用域服务会被多次实例化?
【发布时间】:2020-01-15 18:12:55
【问题描述】:

在我的 ConfigureServices 中,我有许多注册服务,例如:

services.AddScoped<IService1,Service1>();
services.AddScoped<IService2,Service2>();
services.AddScoped<IService3,Service3>();

如果我现在在上面的每一个上都设置一个断点,我会得到预期的行为,即在启动期间断点按预期被命中一次。

但是我现在注册了另一个服务,如下所示:

    services.AddScoped<IWCFService>(service =>
    {
        using (var scope = service.CreateScope())
        {
            var settingData = scope.ServiceProvider.GetRequiredService<AppSettingsDB>();
            var client = new WCFServiceClient(
                WCFServiceClient.EndpointConfiguration.WCF,
                settingData.Url);
            client.Endpoint.EndpointBehaviors.Add(
                new InspectorBehavior<IWCFServiceClient>(settingData.EnableLog));
            return client;
        };
    });

上面的工作正常,但是如果我添加一个断点,我每次请求都会看到它的命中。

我错过了什么还是预期的行为?

【问题讨论】:

  • 需要澄清一下。当您说 hit every time on every request 时,您的意思是针对每个注入它的位置还是针对向 api 发出的每个 HTTP 请求? Scoped 生命周期意味着每个 HTTP 请求范围使用一次,因此这是预期的行为
  • 对于每个 API 请求。之前没有观察到这种行为,所以它可能是正常的,但其他服务上的其他断点不会受到影响。

标签: dependency-injection asp.net-core-3.1


【解决方案1】:

这是预期的行为,因为作用域生命周期意味着对象将在每个请求中初始化一次。因此,您的实现因素委托将在对 API 的每个请求而不是对服务容器(瞬态)的每个调用上被调用。

参考Service lifetimes

作用域

每个客户端请求(连接)创建一次范围生命周期服务 (AddScoped)。

【讨论】:

  • 根据我以前的经验,我认为容器是在启动时创建的,这可能是正确的。
  • 是的,但是每个请求都会调用工厂委托
  • 我明白了。工厂委托做了很多事情,比如从数据库读取数据以创建各种服务,这意味着每个请求都会发生这种情况,数据被缓存所以不是一个大问题,但是考虑到可能有 50 个提高性能的任何其他方法根据请求创建的服务?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-17
  • 1970-01-01
  • 2011-11-21
相关资源
最近更新 更多