【发布时间】:2010-02-02 20:35:43
【问题描述】:
我正在尝试为我的大型 ASP.NET MVC 应用程序创建业务层和数据层。因为这是我第一次尝试这种规模的项目,所以我正在阅读一些书籍,并努力小心地将事情正确地分开。通常我的应用程序混合了业务逻辑和数据访问层,多个业务实体交织在一个类中(当我试图弄清楚在哪里添加东西时,这让我有几次困惑)。
我一直在阅读的大部分内容是将业务层和数据层分开。这看起来一切都很好而且很花哨,但我无法准确地想象在某些情况下如何做到这一点。例如,假设我正在创建一个允许管理员向系统添加新产品的系统:
public class Product
{
public int Id { get; private set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
然后我通过创建一个存储库来分离数据访问
public class ProductRepository
{
public bool Add(Product product);
}
假设我想要求产品名称至少包含 4 个字符。我看不出如何干净地做到这一点。
我的一个想法是扩展 Name 的 set 属性,并且仅在它的长度为 4 个字符时才设置它。但是,创建产品的方法无法知道名称没有被设置,除了 Product.Name != 无论他们传入什么。
我的另一个想法是把它放在存储库的 Add() 方法中,但是我的业务逻辑和数据逻辑就在那里,这也意味着如果 Add 调用失败我不知道是不是业务逻辑失败或因为 DAL 失败(这也意味着我无法使用模拟框架对其进行测试)。
我唯一能想到的是将我的 DAL 东西放在第三层,该层从存储库中的 Add() 方法调用,但我在书中的任何域建模示例中都没有看到这一点或在网络上(至少我见过)。当我不确定是否需要它时,它还会增加域模型的复杂性。
另一个示例是要确保名称仅由一个产品使用。这会放在 Product 类、ProductRepository Add() 方法中,还是放在哪里?
附带说明一下,我计划使用 NHibernate 作为我的 ORM,但是,为了完成我想要的(理论上)我使用什么 ORM 并不重要,因为 TDD 应该能够将它全部隔离。
提前致谢!
【问题讨论】:
-
谢谢大家。一些好东西。我将使用 Juri 的 SoC 解决方案(即实体 -> 服务层 -> 数据层)并将其与 Jay 的第三个验证答案相结合(我喜欢该解决方案的灵活性和清洁度),然后将 AddValidation()暂时调用服务层,直到我为他们找到更好的位置。最后我还把我的 AddValidation 和 IsValid 调用放到了 BaseEntity 类中。
标签: business-logic separation-of-concerns data-access