如何实现存储对象的全局变量?打造跨请求持久化的类内存数据库效果
解决跨请求时内存仓储数据丢失的问题
你的问题根源在于服务生命周期配置错误:当前使用AddTransient注册ITicketRepository,这意味着每次请求(甚至每次从容器获取服务实例)都会创建一个全新的TicketRepository对象——addedTickets作为实例成员,自然会被重新初始化,导致之前的数据全部丢失。
解决方案步骤:
- 修改服务注册的生命周期
将AddTransient替换为AddSingleton,这样整个应用运行期间只会存在一个TicketRepository实例,addedTickets列表会一直保留数据:
builder.Services.AddSingleton<ITicketService, TicketService>(); builder.Services.AddSingleton<ITicketRepository, TicketRepository>();
- 处理多线程并发安全(必做优化)
Web应用是多线程环境,多个请求同时调用AddNewTicket时,直接操作List<Ticket>会引发线程安全问题(比如数据覆盖、集合损坏)。推荐两种处理方式:
方式一:使用线程安全集合ConcurrentBag<Ticket>
public class TicketRepository : ITicketRepository { private readonly FakeDbContext _context; private readonly ConcurrentBag<Ticket> _addedTickets = new ConcurrentBag<Ticket>(); public TicketRepository() { _context = new FakeDbContext(); } public bool AddNewTicket(Ticket ticket) { _context.Tickets.Add(ticket); _addedTickets.Add(ticket); return true; } // 如需获取所有Ticket,返回副本避免外部修改 public IEnumerable<Ticket> GetAllTickets() { return _addedTickets.ToList(); } }
方式二:使用锁机制保护列表操作
public class TicketRepository : ITicketRepository { private readonly FakeDbContext _context; private readonly List<Ticket> _addedTickets = new List<Ticket>(); private readonly object _lockObj = new object(); public TicketRepository() { _context = new FakeDbContext(); } public bool AddNewTicket(Ticket ticket) { _context.Tickets.Add(ticket); lock (_lockObj) { _addedTickets.Add(ticket); } return true; } }
额外注意
如果你的FakeDbContext也需要跨请求保留数据,要确保它的生命周期和TicketRepository一致——要么将FakeDbContext也注册为Singleton,要么在TicketRepository中保持它作为实例成员(因为Singleton的TicketRepository只会初始化一次FakeDbContext)。
内容的提问来源于stack exchange,提问作者Masoud
相关产品推荐
相关产品推荐

