我正在尝试创建一个松散耦合,高度可测试,具有良好干净代码等的小型演示Web应用程序。总之,我正在尝试以正确的方式做事。 ;)
我目前在Wolfie解决方案中有三个项目:
目前,Core对任何其他项目一无所知。数据必须引用Core,因为Core具有Data将返回的类型。所以在这一点上,我发现自己意识到Web需要引用Core和Data才能工作,因为实体类型在Core中,数据库调用在Data中。
Data中的所有存储库类都有接口,因此可以模拟存储库以进行测试。
我认为我不想将任何特定于数据库的代码或引用放入Core中,并且我希望将实体业务规则保留在数据之外。
是否正确从Web引用这两个项目?或者是否需要Web和其他项目之间的另一个项目,以便Web仅引用一个地方,然后不负责调用数据方法等。
我的目标是一个架构,我的核心应用程序独立于数据层和Web层。
我希望我已经做了一些感觉,我期待一些有用的回复。
答案 0 :(得分:9)
我认为您正在努力实现一个合理的目标,这将创建一个可靠的应用程序架构。我个人致力于一个企业Web应用程序,该应用程序使用与您描述的类似的体系结构,并且它对该应用程序非常有效。
在该应用程序中,域业务逻辑在其自己的“域”程序集(您的“核心”程序集)中被隔离,并且在.NET框架之外没有引用任何内容。为了连接到外部业务组件,例如数据库和其他Web服务,有一个“基础结构”程序集(您的“数据”程序集)。该应用程序的关键是基础结构程序集中的每个实现都在域程序集中进行了接口,并返回了域程序集对象(就像您描述的那样)。当然,这需要从基础设施到域的参考。
为了将它们组合在一起,“WebApp”程序集(“Web”程序集)引用了域和基础结构程序集,并使用IoC容器来解析所有应用程序依赖项。当请求进入WebApp时,它将解析相应的“域”合同以提供启动IoC解析调用链的请求。在注册基础结构实现之外,WebApp程序集并不关心基础结构程序集是否存在。
这个应用程序运行良好的原因是它实现了您在问题中所述的目标:
这为您的业务领域提供了批次可测试性,以及批次在前端与您的域的接口方面的灵活性。事实上,这种灵活性 是什么使它如此可测试。这种灵活性也有其他好处。例如,如果您的业务域是隔离的,那么如果您想部署和运行客户端,则可以轻松编写一个新的CLI或WPF前端,这些前端连接到文件系统后端,而不会更改一小块业务域代码在机器上本地。
虽然这个例子看起来有些牵强,但就上面引用的应用程序而言,开发团队正在考虑构建一个Web Services前端,以补充已经存在的MVC网站前端。这对于该团队来说只是一个现实的可能性,因为他们像您所描述的那样设置了该应用程序。
答案 1 :(得分:4)
我认为这两个参考文献没有任何内在错误。
但是,我会考虑“核心”是什么。这是你的域逻辑吗?如果是这样,我不确定我的数据访问程序集会知道您的域逻辑并且您的GUI层知道这两者。
如果“Core”是域逻辑,则可以在其中放置知道“数据”程序集的类(例如IRepository Pattern)。然后,您的Web程序集将知道“Core”,而不是“Data”。
为了便于这种安排,您可以创建一个名为“DataTransfer”的第四个程序集,并定义一些“Core”,“Data”和“Web”都知道并用于与之通信的对象(或更好的接口)另一个。事实上,如果你真的想要解耦,那么使用包含接口的“类型”程序集来构造事物实际上可以使原始的三个程序集中没有一个知道彼此。
但是,如果“Core”实际上是一个库而不是你的域逻辑,那么可能有必要使用当前的结构,如果添加足够的功能来开始添加更多的程序集/层,可能会重新访问它。 / p>
编辑:为了帮助想象我的意思,我说的是分层的情况:
Web
|
v
Core
|
v
DataAccess
而不是:
Web
| \
v \
Core |
^ |
| v
DataAccess
如果可以使用两个引用,则有三个引用。早期的额外/不必要的耦合会导致后来的麻烦。
答案 2 :(得分:3)
你很有意义,你的推理非常合理。 Web层引用Core和Data是一种非常常见,合理和实用的设计。你没有创建任何循环引用并保持它非常干净。
答案 3 :(得分:1)
架构是1.数据2.业务逻辑3.客户端。数据就是数据。业务逻辑适用于数据。客户端连接到业务逻辑,如data->业务逻辑 - >客户端。客户端不直接连接到数据。 3层。数据逻辑客户端。
答案 4 :(得分:1)
我认为这是有道理的。只要您将Web与业务层分开,它就可以让您更轻松地测试业务逻辑,并通过其他方式(例如,Web服务)公开业务层。