我一直在阅读有关将业务逻辑放在ASP.NET MVC项目中的位置,我仍然无法弄清楚某些事情.
1 - 领域模型.这些真的是什么?在我的Model文件夹中,我只有一堆与我的数据库对应的类.我先使用EF代码.我认为这些是我的域模型.
2 - 服务层.这个答案暗示了一个服务层,我觉得这很有道理.我决定和这个一起去.然而,Martin Fowler的"贫血领域模型"文章搞砸了我的想法.
我不确定如何为我的域模型添加逻辑.
我经历了许多与业务逻辑相关的问题,每个问题都提出了1或2.我不明白的是我如何实现第一个问题.向实体类添加方法(对我来说是域模型)根本没有意义.为什么第二种方法被认为是坏的?
asp.net-mvc business-logic domain-model service-layer anemic-domain-model
我有一个设计精良的架构,控制器访问服务,这些服务访问与数据库通信的存储库.
因此,控制器中的逻辑保持在最低限度,但我仍然有非常微妙的代码片段来执行某些任务
一些较长的情况根据服务返回的"状态"执行不同的操作.
这里有几个例子:
[HttpPost]
[AjaxOnly]
[Authorize]
public JsonResult Preview(string input)
{
LinkResult parsed = linkService.ParseUserInput(input);
if (parsed.Result == LinkParseResult.Used)
{
long? postId = parsed.Link.PostId;
if (postId.HasValue)
{
Post post = postService.GetById(postId.Value, false);
return Json(new
{
faulted = "used",
link = DetailsRoute(post),
id = postId
});
}
else
{
return Json(new { faulted = "invalid" });
}
}
else if (parsed.Result == LinkParseResult.Invalid)
{
return Json(new { faulted = "invalid" });
}
else
{ …
Run Code Online (Sandbox Code Playgroud) 将数据库实体映射到模型和执行业务逻辑的最佳实践是什么?我已经看到两者的实现差异很大.我注意到了许多实现,其中Repository(在数据层中)本身负责将数据库实体映射到域模型.例如,一个可以执行此操作的存储库:
public IQueryable<Person> GetPersons()
{
return DbSet.Select(s => new Person
{
Id = s.Id,
FirstName= s.FirstName,
Surname= s.Surname,
Location = s.Location,
});
}
Run Code Online (Sandbox Code Playgroud)
但是在N Tier设计上全面搜索SO时,我注意到虽然没有银弹,但在大多数情况下,建议手动或使用Mapper在MVC项目中执行控制器内的映射.还有人重申,服务层永远不应该执行映射,并且它应该负责执行业务逻辑.这里有几个问题:
Person
enities 的全名,或者将所有Person
s 的年龄增加10年,应该在哪里执行此操作.在模型本身?例如,我会FullName
在模型上有一个属性来计算全名和年龄吗?或者我在服务层内定义一些服务来执行业务逻辑?编辑
哇这么多亲密的选票.道歉,我没有全面搜索.我在这里提出的"在哪里执行业务逻辑"问题已经可以在SO和其他地方找到(虽然有时会有些隐晦地传达):
但是我还没有找到我所遇到的映射问题的标准解决方案,而且我想我也许可以更有说服力地表达我的问题.因此,普遍的共识似乎是业务逻辑进入服务层,将域模型映射到视图模型应该在控制器/表示层中进行.并且由于建议不要将数据库实体映射到数据层以外的任何层,因此建议您手动或通过映射器(如Auto Mapper)将实体映射到数据层的域模型(这是我从阅读很多文章).我的困惑源于将实体映射到域模型以及将域模型映射到视图模型的问题.然而,正如我之前提到的,我可以更清楚地表达我的问题.我混淆的原因是我已经读过,映射实体到域模型应该在控制器中发生,这应该改为说"将实体映射到域模型应该在以后的数据中发生,并将域模型映射到视图模型应该在控制器中进行.
看过Rob Conery的Kona应用程序的样本后,我发现他正在使用IoC - ISession,他有数据层代码和服务,他在操作数据存储区中的数据时需要执行一些额外的业务逻辑.例如,我们可能不仅仅是向DB添加记录,而且还改变了另一条记录的属性,增加了一些计数,取回了一些东西等等.我们需要将这些额外的代码放在一边,并将它放在那些服务中.
例如,他有一个操纵客户的CustomerService.这要求我们将ISession实例发送到CustomerService,以便CustomerService可以使用它来访问数据存储区.
现在另一种方法是将其他代码放在Customer类本身,并将ISession(或IRepository,无论我们使用的术语)发送到该类.而且没有任何服务.通常,Customer,Order,Product等类是Model类,因此会导致大/重模型类.
我的问题是,哪种解决方案更好?到目前为止,我没有必要,因为我在控制器中有大部分代码,但现在随着应用程序的增长,我需要对此做出决定并清理控制器.
目前我有: - 具有业务逻辑的胖控制器, - 非常原子的存储库, - 非常干净的模型和视图模型.
我应该转到: - 超薄控制器, - 包含更多代码的存储库, - 具有业务逻辑代码的模型(特别是我的模型类包含Add(),Remove()等方法,例如Customer.Remove()??)
或者 - 苗条的控制器, - 原子库, - 仍然是干净的模型, - 服务(以封装其他任何不属于前者的东西).