依赖注入与分层体系结构

本文关键字:体系结构 分层 注入 依赖 | 更新日期: 2023-09-27 18:25:14

我读了很多关于依赖注入和服务定位器(anti-?)模式的文章,其中很多都是关于StackOverflow的(谢谢大家:)。我有一个问题,当这个模式在n层架构中时,它是如何工作的。

我看过很多博客文章,其中描述了将IDataAccess组件注入业务对象。例如

public class Address
{
    IDataAccess _dataAccess;
    public Address(IDataAccess dataAccess)
    {
        this._dataAccess = dataAccess;
    }
}

然而,我的印象是,在n层架构中,UI层不需要对数据访问层有任何了解。。。甚至知道有数据访问层!如果DI要求在BusinessObjects的构造函数中公开IDataAccess接口,那么这将向UI公开业务层在后台使用数据访问层这一事实——UI肯定不需要知道或关心这一点吗?

所以,我的基本问题是:DI是否要求我向所有上层公开所有下层接口,这是好事还是坏事?

感谢

编辑:为了澄清(在几条评论之后),我知道我的业务对象应该不知道它使用的IDataAccess的哪个特定的实现(因此在构造函数中注入了依赖项),但我认为BO之上的层不应该知道业务对象甚至需要对DAL的依赖项。

依赖注入与分层体系结构

这确实是一个相当复杂的主题,有很多方法可以实现n层架构。没有一种方式是"正确的方式",你如何做到这一点取决于你的需求,也取决于你个人的偏好。

依赖项注入是关于管理依赖项的。如果您的对象不知道任何依赖关系,那么您就不会按照您提到的方式编写对象。相反,您将拥有一些其他服务或方法,这些服务或方法将以不可知的方式填充数据。数据也不意味着"数据库"。所以IDataAccess可能意味着它来自数据库,或者来自网络套接字,或者来自磁盘上的文件。这里的重点是Address不会选择它创建的依赖项。这是通过组合根目录下的配置完成的。

事情需要数据,否则你的应用程序可能毫无用处。然而,让Address对象自己加载可能不是处理事情的最佳方式。更好的方法可能是使用工厂类或服务方法。

我认为答案相当简单。底层(接口、bll、dal、实体)只是一堆libraries。由客户决定使用哪些库,这将增加客户的灵活性。此外,它们是库,因此任何与应用程序相关的配置(连接字符串、数据缓存等)都位于客户端。这些配置本身,有时也需要注入并包含在CompositionRoot中。

但是,如果您想要uniform logic而不是客户端的灵活性,则可以选择web/应用程序服务作为附加层。

1st Layer        Entities
2nd Layer       Interface
3rd Layer       BLL  &  DAL
4th Layer    Web/App Services
5th Layer           UI

这样,你的作文根就存在于一层(第四层)。添加UI只需要将服务引用添加到第4层(如果需要,则添加到第1层)。然而,这再次暗示了Mark Seeman的文章,分层是值得映射的。我认为您可以将app/web service更改为Composition Root

此外,这种(应用程序/网络服务)设计也有利弊。优点:

  1. 您的应用程序已封装

    您的应用程序正在通过应用程序/web服务进行桥接。保证您的UI不知道DataAccess,从而满足您的要求。

  2. 你的应用程序是安全的

    简单地说,用户界面需要访问应用程序服务,这在安全方面是一个巨大的收获。

  3. 访问可移植性

    现在,您的应用程序可以随时随地访问。它可以通过第三方应用程序(其他网络)连接,而无需依赖dll。

缺点:

  1. 服务呼叫期间的间接费用

    身份验证、网络连接等会在Web服务调用过程中造成开销。我对性能影响没有经验,但对于高流量应用程序来说应该足够了。

  2. 客户端不灵活

    客户端现在需要使用服务而不是普通对象来访问BLL/服务。

  3. 为不同类型的客户端提供更多服务

    现在,您需要提供比所需更多的服务。如WebRequestRetrieverMobileRequestRetriever而不是访问一个单纯的IRequestRetriever,并让组成根线连接其余部分

如果这个答案超出了主题,请道歉(完成后才意识到)。

IMHO:

这取决于谁注射!-

你似乎需要/期望有一个MVC或MVP架构,其中控制器或演示者负责将UI调用来回转换为业务对象创建IDataAccess的具体实现,将其发送到Address类。这样UI就完全不知道是谁在提供它需要的数据,并且它为您提供了预期的可伸缩性。

谢谢Tarriq