【发布时间】:2019-11-05 08:07:06
【问题描述】:
使用 ASP.NET Core 3.0 我有一个 PostService,它可以读取一些 Markdown 文件的内容:
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;
}
}
我在控制器上按如下方式使用它:
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
}
}
我不想在每个请求中加载文件,因为它们不会改变。
我应该将 PostService 添加为 Singleton 吗?
services.AddSingleton<IPostService, PostService>();
我应该将帖子存储在 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;
}
}
这是要走的路吗?我应该在构造函数中加载帖子吗?
【问题讨论】:
-
将此作为服务的目的是什么?测试?
-
是的,用于测试......并且还有一个类负责加载和解析将在一些控制器中使用的文件。
-
是否有可能同时调用
GetAllAsync()?如果是这样,静态变量解决方案可能会遇到变量被多次加载的问题,如果/当多个请求进入方法而变量仍然为空时 -
你考虑过把它放到cache吗?
-
@devNull 是的,处于可能发生的 Web 应用程序中。
标签: c# asp.net-core asp.net-core-3.0