为什么我的范围依赖项在单个范围内实例化了两次?

时间:2021-07-26 12:11:04

标签: dependency-injection .net-5

假设我有一个单例,它有一个 Scoped 依赖(并且永远被单例持有)。

然后我创建一个范围并从容器中获取 Singleton 和 Scoped 实例。 我希望 Scoped 在单个范围内仅实例化一次。

请看一个简化的代码示例:

namespace TrivialConsole
{
    using Microsoft.Extensions.DependencyInjection;
    using System;

    class Program
    {
        static void Main(string[] args)
        {
            var services = new ServiceCollection();
            services.AddScoped<Scoped>();
            services.AddSingleton<Singleton>();

            var provider = services.BuildServiceProvider();
            using (var rootScope = provider.CreateScope())
            {
                var scopeProvider = rootScope.ServiceProvider;
                var singleton = scopeProvider.GetRequiredService<Singleton>();
                var scoped = scopeProvider.GetRequiredService<Scoped>();
            }
        }
    }

    public class Singleton
    {
        private static int instances = 0;

        private readonly Scoped scoped;

        public Singleton(Scoped scoped)
        {
            instances += 1;
            this.scoped = scoped;
            Console.WriteLine($"singleton {instances}");
        }
    }

    public class Scoped
    {
        private static int instances = 0;

        public Scoped()
        {
            instances += 1;
            Console.WriteLine($"scoped {instances}");
        }
    }
}

结果:

scoped 1
singleton 1
scoped 2

预期结果 ->

scoped 1
singleton 1

1 个答案:

答案 0 :(得分:1)

根据文档,不应将作用域类型注入到此框架中的单例中。

<块引用>

不要从单例中解析范围服务,并注意不要 间接地这样做,例如,通过临时服务。有可能 导致服务在处理后续时状态不正确 要求。没问题:

  • 从作用域或瞬态服务解析单例服务。
  • 从另一个范围服务或临时服务解析一个范围服务。

Reference