我们有一个非常常见的架构:
数据库
存储库层
Business Objects
服务层 - 为客户提供DTO
网络层(MVC)
我们有许多共同的资源路径,特别是图像和播客(例如http://media.mysite.com/podcasts/)。我想创建一个带有属性的静态实用程序类:
MySite.Utils.ImagePathUri
MySite.Utils.PodcastsPathUri
等
我的问题是:你把uri路径放在哪里?该实用程序类进入哪个项目?
最初,它似乎是一个明智的选择:网络层。这是一个网站。我应该能够在没有其他层知道的情况下更改站点的URL。
一切都很好,但是,。 。 。然后有一天我需要提供一个SyndicationFeed类型的服务。 SyndicationFeed需要一个完整的URI,而不仅仅是部分文件名。但是服务不应该访问完整路径。或者他们应该?
我曾与自己辩论过几件事,但无法提出坚定的立场:
你有什么想法?您在哪里放置Web资源(图像,播客等)的实用程序类?如果你说“网络层”,你对SyndicationFeed问题的看法是什么?
更新
在一天结束时,我决定废弃SyndicationFeed类,这样就无需在服务和存储库层中包含文件的路径。然而,问题仍然出现在其他地方并使用DI,特别是像Ninject这样的IoC非常有意义。将这些包装在一个通用界面中也是如此。
SyndicationFeed,查看引擎以及为什么Declarative做声明更好
我放弃了SyndicationFeed,而是使用Razor创建了我需要的XML。它不仅更容易创建,而且可读性提高了1000%。我认为使用命令式代码(C#,VB等)创建XML比它应该更难。 XML是声明性的,而不是命令式的。
相反,我现在已经决定使用View Engines(例如Razor)的声明性语法比命令式语言更容易使用。
答案 0 :(得分:1)
我感觉到你的痛苦。我也有类似的情况,我通过将uri传递到我的存储库层,从我的网络层解决了这个问题。
我的项目使用Ninject进行绑定,因为我已经使用Ninject将连接字符串传递给存储库,所以传递路径字符串也很简单。
我的存储库然后按摩路径字符串并在我的业务对象中填充必要的属性。
这是正确的吗?我不知道,但它现在有效。我对解决方案并不完全满意,但我还没有机会尝试改进。
很想听听其他人如何处理这件事。
答案 1 :(得分:1)
面对类似的情况,我觉得接近它的最佳方法是定义一个配置界面,该界面导致最顶层的对象。中间的每一层都会使用更具体的属性和操作来优化界面:
public interface IWebConfiguration
{
string RootImageUri { get; }
}
服务层将添加自己需要的东西:
public interface IServicesConfiguration
{
string SyndicationFeedUri { get; }
}
public interface IDatabaseConfiguration
{
string ConnectionString { get; }
}
最后,我让Web层实现了连接所有接口的特定对象。丑陋?也许。我承认在那里有一些叫 isa 和一些演员。
然而,我能够将每个层传递给强类型接口。在我看来,这比从一个配置文件中获取普通旧字符串的一系列调用要好。此外,因为每个属性都是特定于图层的,并且聚合对象被传递,所以我只需要加载一次配置。