我正在构建一个应用程序,现在我为每个控制器提供一个服务(该服务处理控制器的业务逻辑)。每个服务都有自己的dbcontext。
我已经认识到有几个服务需要执行相同的功能(从数据库中检索相同的数据列表,并在返回之前对它们执行相同的逻辑)。理想情况下,我需要一种方法让服务访问常用功能。
我的第一个想法是创建一个每个服务都可以使用的简单助手类,使用简单的函数将dbcontext作为参数之一,这样函数就可以执行数据库查询和逻辑并返回结果。 / p>
这是个好主意吗?我会通过这种方式构建我的代码遇到问题,还是我应该采用更好的更强大和更可接受的方法?
答案 0 :(得分:1)
我说你正走在正确的轨道上,但是采取单一责任原则更进一步。 http://blog.codinghorror.com/curlys-law-do-one-thing/。它是保持代码清洁的成熟策略。我避免"帮助"每个人说的课程。有太多的责任,他们可能会变得混乱。相反,我试着真正考虑我班级应该做什么。然后我给它一个非常好的名字,提醒我它只做那件事。
您的服务每个都有自己的Db上下文这一事实可能是个问题。如果您调用了多个从属于同一个Db上下文的依赖服务,请确保它们全部。如果你的对象图很大,像AutoFac这样的容器将是一个很大的帮助。
答案 1 :(得分:1)
返回的数据是否相同?他们是使用自己独特的数据库上下文还是相同的数据库上下文?
通常我会建议避免创建一个帮助类。通常,辅助类用于操作对象而不是执行数据库查询。
根据您的评论,您可以通过两种方式实现此目标,一种方式比另一种方式更容易。
选项1:
如果你的申请真的是一个简单的申请,你不太关心做事,那就是纠正'那么你可以简单地创建基本服务类并更新你的服务来扩展它,并将你的公共数据库访问移动到基类中,如下所示:
abstract class BaseService
{
...
public ICollection<ExampleRecord> GetDatabaseRecords()
{
using (var context = new ApplicationDbContext())
{
/* Your DbContext code */
}
return databaseRecords;
}
...
}
然后像这样扩展BaseService
:
public class ExampleService : BaseService
{
...
public ICollection<ExampleRecord> GetRecords()
{
return this.GetDatabaseRecords();
}
...
}
这样可以完成工作并成为您当前所做工作的更好选择,但这通常不是最佳方法。
Optios 2:
如果您的应用程序不仅仅是一个简单的应用程序并且您关注代码可维护性,那么我建议您考虑将数据库访问代码移动到单独的存储库类中,并使用IoC容器(如StructureMap)将其注入通过依赖注入将存储库表示到您的服务中。
就我个人而言,我会建议选项2,因为它更清晰,更易于维护/可扩展,并且您没有违反任何SOLID principles。
答案 2 :(得分:0)
您可以使用抽象服务来定义常用方法 这是一个很好的教程 generic repository, services layer, IoC, unit test an entity framework