为什么我的作用域服务每次都被称为新实例?

Why is my scoped service being called as a new instance every time?

这是一个练习 ASP.NET 项目,我用它来更好地理解一些技术,虽然我已经让依赖注入工作了,但它并没有像我想要的那样工作。我有一个 class 想用来存储历史记录,所以每次用户点击提交按钮时,它都会显示一个结果,第二次后它开始显示历史记录。无论如何,我将历史记录作为范围服务添加到 DI,认为这意味着它会被创建,然后在该用户的会话期间保持相同的实例。然而,根据调试器,列表看起来永远不会大于 1,这就是将项目添加到列表的时候。所以代码。

对象

{
    public class RollHistory : IRollHistory
    {
        public List<IRollMessage> Entries { get; set; } = new List<IRollMessage>();
    }
}

DI

public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddTransient<IDiceTray, DiceTray>();
            services.AddTransient<IRollMessage, RollMessage>();
            services.AddScoped<IRollHistory, RollHistory>();
        }

控制器构造函数

public HomeController(ILogger<HomeController> logger, IDiceTray diceTray, IRollMessage rollMessage, IRollHistory rollHistory)
    {
        _logger = logger;
        _diceTray = diceTray;
        _rollMessage = rollMessage;
        _rollHistory = rollHistory;
    }

以及按钮被点击时的代码

[HttpPost]
    public IActionResult Index(DiceRollModel diceRoll)
    {
        _diceTray.DiceRoll(diceRoll.DiceType, diceRoll.DiceCount, diceRoll.Bonus, diceRoll.VantageType);
        _rollMessage.RollMessages(_diceTray);
        diceRoll.RollResult = _rollMessage;
        _rollHistory.Entries.Add(_rollMessage);
        diceRoll.History = _rollHistory.Entries;
        return View(diceRoll);
    }

值得注意的是,我已经尝试使用和不使用 DI 以至少 4 种不同的方式对此进行编码,唯一可行的方法是使用 AddSingleton,虽然这可能不是问题,因为此应用不太可能永远直播吧,这是不做正确的借口。

我相信“范围”默认是每个请求,这将解释每个提交得到的是自己的服务。

“做正确的事情”当然在某种程度上是见仁见智的。但我的意见显然是我会避免服务器端会话,以避免扩展到多个实例时出现问题。也有支持共享状态的方法,但这很难。对我来说,单身人士也不是代码味道,但他们有自己的问题。

您的问题可能会通过将浏览器中需要的任何状态存储在 cookie 或 localStorage 中来解决。然后,您的服务将具有请求范围,但它会从浏览器读取用户状态,从而导致数据的“用户范围”。 (但不要依赖浏览器状态来保持并记住它对用户是可修改的。)