我一直在阅读很多关于依赖注入和服务定位器(反?)模式的东西 - 很多关于StackOverflow(感谢大家:) . 我有一个关于这种模式在n层架构中如何工作的问题 .
我看过很多博客文章,他们描述了将IDataAccess组件注入业务对象 . 例如 .
public class Address
{
IDataAccess _dataAccess;
public Address(IDataAccess dataAccess)
{
this._dataAccess = dataAccess;
}
}
但是,我的印象是,在n层架构中,UI层不需要具备数据访问层的任何知识......甚至不需要知道/是/数据访问层!如果DI要求在BusinessObjects的构造函数中公开IDataAccess接口,那么这会向UI公开业务层使用数据访问层的事实 - UI不需要知道或关心的事情是什么?
所以,我的基本问题是:DI是否要求我将所有下层接口暴露给所有上层,这是好事还是坏事?
谢谢
编辑:为了澄清(在几条评论之后),我知道我的业务对象应该不知道它使用哪个IDataAccess特定的 implementation (因此在构造函数中注入依赖关系)但是我认为BO之上的层不应该知道业务对象甚至 requires 依赖于DAL .
3 回答
恕我直言:
这取决于谁注射! -
您似乎需要/期望拥有MVC或MVP架构到位,控制器或Presenter负责将UI调用转换为业务对象,来回 - 创建IDataAccess的具体实现,将其发送到Address类 . 因此,用户界面完全不知道谁在提供所需的数据,并为您提供了预期的可扩展性 .
谢谢Tarriq
我认为答案很简单 . 你的底层(接口,bll,dal,实体)只是一堆
libraries
. 由客户决定使用哪些库,这将增加客户的灵活性 . 此外,它们是库,因此任何与应用程序相关的配置(连接字符串,数据缓存等)都位于客户端上 . 那些配置本身,有时也需要注入并包含在Composition Root中 .但是,如果您希望具有
uniform logic
而不是客户端的灵活性,则可以选择Web / app服务作为附加层 .这样,您的组合根存在于一个层(第4层)中 . 添加你的UI只需要添加第4层的服务引用(如果需要,可以添加第1层) . 然而,这再次暗示了Mark Seeman的文章,layering is worth the mapping . 我假设您可以将
app/web service
更改为Composition Root
.此外,这个(app / web服务)设计有利弊 . 优点:
您的应用正在通过应用/网络服务进行桥接 . 保证您的UI不知道
DataAccess
,从而满足您的要求 .简单地说,拥有UI需要访问应用服务是安全方面的巨大收获 .
现在您的应用程序可以随处访问 . 它可以通过第三方应用程序(其他网络)连接,而不依赖于dll .
缺点:
身份验证,网络连接等将导致Web服务调用期间的开销 . 我对性能影响缺乏经验,但对于高流量应用来说应该足够了 .
客户端现在需要使用服务而不是普通对象来访问BLL / Services .
现在您需要提供比需要更多的服务 . 例如
WebRequestRetriever
,MobileRequestRetriever
而不是仅仅访问IRequestRetriever
并让组合根连接其余部分 .如果这个答案能够超越主题(在完成后才实现),请道歉 .
这实际上是一个相当复杂的主题,有许多方法可以实现n层架构 . 没有一种方法是“正确的方式”,你如何做到这一点取决于你的需求和个人喜好 .
依赖注入是关于管理依赖关系 . 如果你的对象不知道任何依赖,那么你就不会按照你提到的方式编写你的对象 . 您将改为使用其他服务或方法以不可知的方式填充数据 . 数据也不代表“数据库” . 所以IDataAccess可能意味着它来自数据库,或者它来自网络套接字或来自磁盘上的文件 . 这里的重点是Address不会选择它创建的依赖项 . 这是通过组合根处的配置完成的 .
事情需要数据,否则你的应用可能没用 . 但是,使您的Address对象加载自身可能不是最好的方法 . 更好的方法可能是工厂类或服务方法 .