我们有一个非常常见的架构:
数据库
存储层
业务对象
服务层 - 为客户端提供 DTO
Web 层 (MVC)
我们有许多通用的资源路径,特别是图像和播客(例如http://media.mysite.com/podcasts/)。我想创建一个具有属性的静态实用程序类:
MySite.Utils.ImagePathUri
MySite.Utils.PodcastsPathUri
ETC
我的问题是:你把 uri 路径放在哪里?这个实用程序类进入哪个项目?
最初,这似乎很简单:web 层。这是一个网站。我应该能够在其他层不知道的情况下更改站点的 url。
一切都很好,但是,。. . 然后有一天我的一项服务需要提供 SyndicationFeed 类型。SyndicationFeed 需要完整的 URI,而不仅仅是部分文件名。但是服务不应该访问完整路径。或者他们应该?
我和自己争论了几件事,但无法得出一个坚定的立场:
- 将路径移至服务层。这将 Web 层与服务层紧密耦合,但也许没关系,因为它们从一开始就非常紧密耦合。
- 将路径移动到业务对象或存储库。我不喜欢这样,但如果我愿意将其放入服务层,我至少必须考虑一下。
- 不要在服务层内部使用 SyndicationFeed,而只能在 Web 层中使用它。解决了这个问题,但似乎 SyndicationFeed 应该属于服务层。
- 放弃 SyndicationFeed。任何 SyndicationFeed 都可以更轻松地在 MVC 中创建,使用 PartialView 生成适当的 XML,而不必弄乱像 ElementExtensions 这样臃肿的抽象。我喜欢这个,但是我们在很多地方都使用了 SyndicationFeed,这样一来就可以进行最多的解释。
- 为服务层中的联合提要提供一个虚假的 uri,然后在 Web 层中更改它。你能说黑客吗?
- 将完整路径放入数据库中。起初这听起来不错,但后来我意识到它会在您拥有动态生成的图像时立即中断。
- 我没有想到的其他一些解决方案。
你怎么认为?您将 Web 资源(图像、播客等)的实用程序类放在哪里?如果您说“网络层”,您对 SyndicationFeed 问题有何看法?
更新
最终,我决定废弃 SyndicationFeed 类,它消除了在服务层和存储库层中包含文件路径的需要。然而,问题仍然存在于其他地方,使用 DI,尤其是像 Ninject 这样的 IoC 是非常有意义的。将这些包装到一个通用接口中也是如此。
SyndicationFeed,查看引擎以及为什么声明式声明更好
我放弃了 SyndicationFeed,而是使用 Razor 创建了我需要的 XML。它不仅更容易创建,而且可读性提高了 1000%。我发现使用命令式代码(C#、VB 等)创建 XML 比它应该做的更难。XML 是声明性的,而不是强制性的。
相反,我现在决定视图引擎(例如 Razor)的声明式语法比命令式语言更容易使用。