我正在使用asp.net核心。这是将模型与控制器一起使用的基本方法。
public class BookController : Controller
{
private readonly ApplicationDbContext _context { get; set; }
public BookController(ApplicationDbContext context)
{
_context = context;
}
public IActionResult Create(Book model)
{
// adding new model
}
public IActionResult Edit(Book model)
{
// modifying the model
}
public IActionResult Delete(Book model)
{
// removing the model
}
}
我的问题:什么时候应该/我应该在控制器内实现代码?什么时候应该/我应该在另一个班级实现它?
这样的事情:
public interface IBook
{
int Add(Book book);
int Update(Book book);
int Remove(Book book);
}
public class BookData : IBook
{
private readonly ApplicationDbContext _context { get; set; }
BookData(ApplicationDbContext context)
{
_context = context
}
public int Add(Book model)
{
// ...
return _context.SaveChanges();
}
// other implements...
}
然后,在控制器内调用它:
public IActionResult Create(Book model)
{
var bookData = new BookData(_context);
int result = bookData.Add(model);
// ...
}
对于界面,我认为它可能对案例有用:我有许多控制器需要相同的操作/方法名称。
示例:MessageController
至少需要3个操作/方法(Create/Add
,Edit/Update
,Delete/Remove
)。它与NotificationController
类,CommentController
类......
因此,界面可以改进为:
public interface IMyService<T> where T : class
{
int Add(T model);
int Update(T model);
int Remove(T model);
}
public class MyService<T> : IMyService<T> where T : class
{
private readonly ApplicationDbContext _context { get; set; }
public MyService(ApplicationDbContext context)
{
_context = context;
}
public int Add(T model)
{
Type type = typeof(model);
if (type == typeof(Book))
{
// adding new book model
}
else if (type == typeof(Comment))
{
// adding new comment model
}
// ...
return -1;
}
// other implements...
}
我误解了什么吗?
答案 0 :(得分:2)
如果我使用数据类正确读取它,实际上意味着存储库(这是对持久层的抽象)。您应始终将持久性逻辑封装在类后面(通过存储库模式,命令/查询模式或请求处理程序)并使用它而不是直接使用服务类中的上下文。
话虽这么说,您可以直接将BookData
注入您的控制器,而不是ApplicationDbContext
。您应该考虑在当前实施中丢失的一件事是工作单元模式。现在,每次添加都会立即保留数据。
这可能不是您想要的,因此您应该将_context.SaveChanges();
移到Add/Remove/Update
方法之外并明确地调用它。这允许您插入10个记录,如果其中一个失败,则不会将任何内容保留到数据库中。
但是如果你在每次插入后调用_context.SaveChanges();
并且在第8个(10个)记录中出现错误,那么7个持久化,3个将丢失并且你得到的数据不一致。
控制器根本不应包含任何逻辑,只对输入模型进行简短验证(ModelState.IsValid
检查),如果可以的话,调用执行所有逻辑的服务并将结果报告给用户。仅在非常简单的教程和指南中,为了简单起见,将逻辑放入控制器动作中。在现实世界的应用程序中,你不应该这样做。控制器比服务类更难进行单元测试。