【发布时间】:2021-01-24 20:49:11
【问题描述】:
这是我用来更好地理解一些技术的实践 ASP.NET 项目,虽然我已经让依赖注入工作,但它并没有像我想要的那样工作。我有一个类,我想用它来存储历史记录,所以每次用户点击提交按钮时,它都会显示一个结果,并且在第二次之后它开始显示历史记录。无论如何,我将历史记录作为范围服务添加到 DI,认为这意味着它将被创建,然后在该用户的会话期间保持相同的实例。然而,根据调试器,它看起来列表永远不会大于一个,这就是将项目添加到列表的时候。所以代码。
对象
{
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,虽然这可能不是问题,因为这个应用程序不太可能上线,这是一个不正确的借口。
【问题讨论】:
-
范围是针对每个请求,而不是会话。
-
Transient 也不起作用,所以我该去哪里?
-
如果我记得,asp.net 有一个您可以访问的会话。但不建议存放大件物品。最好的办法是存储在数据库中,并使您的请求无状态——这意味着为每个请求获取和存储数据。
-
存储这种东西似乎有点浪费,我打算将其重写为有限数量的条目并删除最旧的条目,以建立数据库和附带的数据访问它。它只是存储一些短字符串。谢谢,但如果一切都失败了,我可以那样做。
-
It seems a bit of waste to store this kind of stuff, which I intend to rewrite to have a limited number of entries and drop the oldest, to set up a database and the data access that comes with it. Its just storing a few short strings.MemoryCache或带有Dictionary(由会话键入)或 Redis 或数据库的单例对象。
标签: c# asp.net model-view-controller dependency-injection scope