使用 Core 的 DI Singleton 作为内存数据提供程序?



我需要从远程服务(懒惰地(获取站列表,并将其存储在数据库和内存中。
然后,如果有人想要该列表,他会尝试读取内存中的列表。
如果它是空的,它去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;
}
}
}
}

所以现在我在单例类中有一个属性.
当有人要求列表时,我检查它是否为空,然后我去数据库。 如果数据库没有数据,我开始从远程获取并填写列表。

我还添加了 lock ,这样 2 个请求就不会调用两次获取。

问题

这里的东西看起来不对劲。我不确定这是正确的方式。此外,我真的不喜欢这个解决方案。

有没有办法以更优雅/更好的方式做到这一点?

你可以使用 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);  }
}
}

请注意,这不是缓存或访问数据的最佳解决方案,因为您要将提供程序耦合到 Stations 对象。我建议创建一个服务/类并将您的"提供程序"(作为抽象(注入其中,以便反转依赖关系(依赖反转原则(。如果你要创建一个Service/Manager类,你甚至可以注入一个ICacheService并使用MemoryCache实现它。

最新更新