C# 从文件中读取内容一次。。。静态还是单态?
使用ASP.NET Core 3.0,我有一个PostService,它可以读取一些降价文件的内容:C# 从文件中读取内容一次。。。静态还是单态?,c#,asp.net-core,asp.net-core-3.0,C#,Asp.net Core,Asp.net Core 3.0,使用ASP.NET Core 3.0,我有一个PostService,它可以读取一些降价文件的内容: public class PostService : IPostService { private String _basePath; public PostService(IWebHostEnvironment _webHostEnvironment) { _basePath = _webHostEnvironment.WebRootPath; } p
public class PostService : IPostService {
private String _basePath;
public PostService(IWebHostEnvironment _webHostEnvironment) {
_basePath = _webHostEnvironment.WebRootPath;
}
public async Task<IList<Post>> GetAllAsync() {
IList<Post> _posts = new List<Post>();
String[] files = Directory.GetFiles($"{_basePath}/posts", "*", SearchOption.AllDirectories);
foreach (String file in files) {
String content = await File.ReadAllTextAsync(file);
// Process content and create 'post' from content
_posts.Add(post);
}
return _posts;
}
}
公共类邮政服务:IPostService{
私有字符串_basePath;
公共邮政服务(IWebHostenEnvironment\u WebHostenEnvironment){
_basePath=\u WebHostenEnvironment.WebRootPath;
}
公共异步任务GetAllAsync(){
IList_posts=新列表();
String[]files=Directory.GetFiles($“{u basePath}/posts”,“*”,SearchOption.AllDirectories);
foreach(文件中的字符串文件){
String content=wait File.ReadAllTextAsync(文件);
//处理内容并根据内容创建“帖子”
_增加(员额);
}
返回岗位;
}
}
我在控制器上使用它如下:
public class PostController : ControllerBase {
public PostController(IPostService postService) {
_postService = postService;
}
[HttpGet("posts/{id}")]
public async Task<IActionResult> Get(Int32 id) {
Post post = _postService.GetAllAsync().FirstOrDefault(x => x.Id == id);
// Remaining code
}
}
public类后控制器:ControllerBase{
公共邮政控制器(IPostService邮政服务){
_邮政服务=邮政服务;
}
[HttpGet(“posts/{id}”)]
公共异步任务Get(Int32 id){
Post Post=\u postService.GetAllAsync().FirstOrDefault(x=>x.Id==Id);
//剩余代码
}
}
我不想在每个请求中加载文件,因为它们不会更改
我是否应该将邮政服务添加为单身
services.AddSingleton<IPostService, PostService>();
services.AddSingleton();
我应该在PostService中的静态变量中存储帖子吗
避免一直加载和读取文件的最佳方法是什么
更新
在PostService中使用静态字段类似于:
public class PostService : IPostService {
private static List<Post>() _posts;
private String _basePath;
public PostService(IWebHostEnvironment _webHostEnvironment) {
_basePath = _webHostEnvironment.WebRootPath;
}
public async Task<IList<Post>> GetAllAsync() {
// Check if Posts were already loaded.
if (_posts != null)
return _posts; // If yes then return _posts and do not load files
String[] files = Directory.GetFiles($"{_basePath}/posts", "*", SearchOption.AllDirectories);
foreach (String file in files) {
String content = await File.ReadAllTextAsync(file);
// Process content and create 'post' from content
_posts.Add(post);
}
return _posts;
}
}
公共类邮政服务:IPostService{
私有静态列表()_posts;
私有字符串_basePath;
公共邮政服务(IWebHostenEnvironment\u WebHostenEnvironment){
_basePath=\u WebHostenEnvironment.WebRootPath;
}
公共异步任务GetAllAsync(){
//检查是否已加载帖子。
如果(_posts!=null)
return _posts;//如果是,则返回_posts,不加载文件
String[]files=Directory.GetFiles($“{u basePath}/posts”,“*”,SearchOption.AllDirectories);
foreach(文件中的字符串文件){
String content=wait File.ReadAllTextAsync(文件);
//处理内容并根据内容创建“帖子”
_增加(员额);
}
返回岗位;
}
}
这是路吗?我应该在构造函数中加载帖子吗 如果你把这个班级设为单身,你就注定它永远是单身。这个类(我假设)将不仅仅做商店帖子。你可能会发现你需要的不是单身 我将列表存储为静态变量
还有其他方法可以将缓存项保存在内存中,并为此进行了优化(例如System.Runtime.Caching.MemoryCache)。如果将该类设置为单例,则会将其永远定为单例。这个类(我假设)将不仅仅做商店帖子。你可能会发现你需要的不是单身 我将列表存储为静态变量
还有其他方法可以将缓存项保存在内存中,并为此进行了优化(例如System.Runtime.Caching.MemoryCache)。我认为这两种方法都可以
在PostService中使用静态字段
静态构造函数将是线程安全的开箱即用。延迟加载的成员需要是线程安全的 我认为两种选择都可以
在PostService中使用静态字段
静态构造函数将是线程安全的开箱即用。延迟加载的成员需要是线程安全的 我刚刚用更新更新了我的问题。我应该在静态构造函数中加载帖子吗?或者像我在更新中建议的那样?当类开始做的不仅仅是缓存帖子时,可以添加一个新的服务。我不相信谴责的论点:)我想在课堂上这样做的原因之一是,如果将来有人错误地将服务设置为临时服务,那么这不会有问题,因为课堂将“缓存”帖子…@MiguelMoura回应问题和一些评论中的更改。如果您必须注入一些东西(例如IWebHostEnvironment),那么显然很难从静态构造函数获取信息。你有没有想过从类中单独获取这些信息(比如在应用程序启动时),然后从类中访问这些信息?@AngryHacker我更愿意注入这些信息,因为我需要编写一些测试。我刚刚用更新更新了我的问题。我应该在静态构造函数中加载帖子吗?或者像我在更新中建议的那样?当类开始做的不仅仅是缓存帖子时,可以添加一个新的服务。我不相信谴责的论点:)我想在课堂上这样做的原因之一是,如果将来有人错误地将服务设置为临时服务,那么这不会有问题,因为课堂将“缓存”帖子…@MiguelMoura回应问题和一些评论中的更改。如果您必须注入一些东西(例如IWebHostEnvironment),那么显然很难从静态构造函数获取信息。您是否想过从类中单独获取这些信息(比如在应用程序启动时),然后从类中访问这些信息?@AngryHacker我更愿意将其注入,因为我需要编写一些测试。将其作为服务的目的是什么?测试?是的,测试。。。还有一个类负责加载和解析将在几个控制器中使用的文件。是否有可能同时调用
GetAllAsync()
?如果是这样的话,静态变量解决方案可能会遇到问题,因为如果/当多个请求进入方法而变量仍然为空时,可能会多次加载变量。您考虑过将其放入吗?@devNull是的,在web应用程序中可能会发生这种情况。有什么建议