在哪里为 DbContext 添加实用方法?
Where to add utility methods for DbContext?
所以我有一个 ASP.NET MVC 5 应用程序 ASP.NET Identity 2.0 运行。一切都很好,但我想重构我的代码,我想知道我当前的实现有哪些替代方案。让我解释一下。
我在项目的根目录中有控制器,在项目的区域文件夹中也有很多控制器。几乎所有这些都继承自 BaseController
class,后者又继承自 System.Web.Mvc.Controller
。这个 BaseController
看起来像这样:
public class BaseController()
{
protected ApplicationUserManager _userManager;
protected ApplicationRoleManager _roleManager;
protected readonly MyDbContext _db = new MyDbContext();
public BaseController()
{
}
public BaseController(ApplicationUserManager um, ApplicationRoleManager rm)
{
UserManager = um;
RoleManager = rm;
}
public ApplicationUserManager UserManager { ... }
public ApplicationRoleManager RoleManager { ... }
#region Utility Methods
// Here are over 60 utility methods that are basically queries on _db
#endregion
}
更多方法正在开发中,我不禁觉得有比将它们放在基础中更好的方法 class 从逻辑上讲,并非每个控制器都应该直接继承这些方法。
将它们移动到 MyDbContext
(继承 IdentityDbContext
)实际上只是将它们移动到 更适用的 文件。我想象的是 MyDbContext
中的每个 DbSet 都有自定义实用程序方法,但我不确定该怎么做。像下面这样的东西是理想的:
Semester thisSemester = _db.Semesters.GetCurrentSemester();
或
SelectList semesters = _db.Semesters.GetAllSemestersAsSelectList();
其中 Semesters
在两个示例中都是 DbSet<Semester>
类型。
谁能提供解决方案?
当我看到类似...的方法时
_db.Semesters.GetAllSemestersAsSelectList()
...我认为这将是一种扩展方法(除非您有自己的 DbSet
实现)。但是扩展方法是为真正通用的任务设计的,而不是为这样的特定任务设计的。此外,它要求在任何你想要这个 select 列表的地方你都可以访问 DbSet
最好在服务中执行此操作 class 这样您就可以调用类似
的方法
_semesterService.GetAllSemestersAsSelectList()
这项服务可能看起来像
class SemesterService : ISemesterService
{
private readonly MyDbContext _context;
/// <summary>
/// Constructor in which an IoC container can inject a context.
/// </summary>
/// <param name="context"></param>
public SemesterService(MyDbContext context)
{
this._context = context;
}
public SelectList GetAllSemestersAsSelectList()
{
return new SelectList(_context.Semesters, "Id", "Name");
}
public Semester GetCurrentSemester()
{
return _context.Semesters.Where(....).FirstOrDefault();
}
}
举个例子。
可能从服务 return 学期开始并在 MVC 控制器中构建 SelectList
更好,这样服务层就不会依赖 MVC。
所以我有一个 ASP.NET MVC 5 应用程序 ASP.NET Identity 2.0 运行。一切都很好,但我想重构我的代码,我想知道我当前的实现有哪些替代方案。让我解释一下。
我在项目的根目录中有控制器,在项目的区域文件夹中也有很多控制器。几乎所有这些都继承自 BaseController
class,后者又继承自 System.Web.Mvc.Controller
。这个 BaseController
看起来像这样:
public class BaseController()
{
protected ApplicationUserManager _userManager;
protected ApplicationRoleManager _roleManager;
protected readonly MyDbContext _db = new MyDbContext();
public BaseController()
{
}
public BaseController(ApplicationUserManager um, ApplicationRoleManager rm)
{
UserManager = um;
RoleManager = rm;
}
public ApplicationUserManager UserManager { ... }
public ApplicationRoleManager RoleManager { ... }
#region Utility Methods
// Here are over 60 utility methods that are basically queries on _db
#endregion
}
更多方法正在开发中,我不禁觉得有比将它们放在基础中更好的方法 class 从逻辑上讲,并非每个控制器都应该直接继承这些方法。
将它们移动到 MyDbContext
(继承 IdentityDbContext
)实际上只是将它们移动到 更适用的 文件。我想象的是 MyDbContext
中的每个 DbSet 都有自定义实用程序方法,但我不确定该怎么做。像下面这样的东西是理想的:
Semester thisSemester = _db.Semesters.GetCurrentSemester();
或
SelectList semesters = _db.Semesters.GetAllSemestersAsSelectList();
其中 Semesters
在两个示例中都是 DbSet<Semester>
类型。
谁能提供解决方案?
当我看到类似...的方法时
_db.Semesters.GetAllSemestersAsSelectList()
...我认为这将是一种扩展方法(除非您有自己的 DbSet
实现)。但是扩展方法是为真正通用的任务设计的,而不是为这样的特定任务设计的。此外,它要求在任何你想要这个 select 列表的地方你都可以访问 DbSet
最好在服务中执行此操作 class 这样您就可以调用类似
的方法_semesterService.GetAllSemestersAsSelectList()
这项服务可能看起来像
class SemesterService : ISemesterService
{
private readonly MyDbContext _context;
/// <summary>
/// Constructor in which an IoC container can inject a context.
/// </summary>
/// <param name="context"></param>
public SemesterService(MyDbContext context)
{
this._context = context;
}
public SelectList GetAllSemestersAsSelectList()
{
return new SelectList(_context.Semesters, "Id", "Name");
}
public Semester GetCurrentSemester()
{
return _context.Semesters.Where(....).FirstOrDefault();
}
}
举个例子。
可能从服务 return 学期开始并在 MVC 控制器中构建 SelectList
更好,这样服务层就不会依赖 MVC。