我需要从远程服务(懒惰地)获得电台列表,并将其存储在DB和内存中。
然后,如果有人想要该列表,则尝试读取内存中的列表。
如果为null,则转到Db,如果DB中没有数据,则应转到远程服务,获取列表,并将列表存储在DB和内存中。
(基本上,我不想每次请求都去远程服务)
因此,我使用了.net核心的单例服务:
services.AddSingleton<IStations,Stations>()
该类将包含列表本身的位置:
public class Stations:IStations
{
public List<StationModel> LstStationModel
{
get
{
lock (locker)
{
if (_lstStationModel == null)
{
var ls = GetStationsFromDb().Result;
if (ls!=null && ls.Count > 0)
_lstStationModel = ls;
else
_lstStationModel = GetStationsFromProvider().Result;
}
return _lstStationModel;
}
}
set
{
lock (locker)
{
_lstStationModel = value;
}
}
}
}
所以现在我在单例类中有一个属性。
当有人要求列表时,我检查它是否为null,然后转到db。
如果数据库中没有数据,我将开始从远程获取并填充列表。
我还添加了lock,以便2个请求不会调用两次提取。
问题
这里的东西看起来不正确。我不确定这是正确的方法。而且,我真的不喜欢这种解决方案。
有什么方法可以更优雅/更好地做到这一点?
答案 0 :(得分:1)
您可以为此目的使用Lazy。如果在构造函数中传递true,则表明它是线程安全的。 示例:
public class Stations : IStations
{
Lazy<List<StationModel>> _lazyStation = new Lazy<List<StationModel>>(() => Provider.GetStationsFromProvider().Result, isThreadSafe: true);
public List<StationModel> LstStationModel
{
get { return _lazyStation.Value; }
set { _lazyStation = new Lazy<List<StationModel>>(() => value, isThreadSafe: true); }
}
}
请注意,这不是缓存或访问数据的最佳解决方案,因为您正在将Provider耦合到Stations对象。我建议创建一个服务/类,然后将您的“提供者”(作为抽象)注入其中,以反转依赖关系(Dependency Inversion Principle)。如果您将创建Service / Manager类,甚至可以注入ICacheService并使用MemoryCache
实现