首页 文章

依赖注入与分层体系结构

提问于
浏览
2

我一直在阅读很多关于依赖注入和服务定位器(反?)模式的东西 - 很多关于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 回答

  • 2

    恕我直言:

    这取决于谁注射! -

    您似乎需要/期望拥有MVC或MVP架构到位,控制器或Presenter负责将UI调用转换为业务对象,来回 - 创建IDataAccess的具体实现,将其发送到Address类 . 因此,用户界面完全不知道谁在提供所需的数据,并为您提供了预期的可扩展性 .

    谢谢Tarriq

  • 1

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

    但是,如果您希望具有 uniform logic 而不是客户端的灵活性,则可以选择Web / app服务作为附加层 .

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

    这样,您的组合根存在于一个层(第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 .

    • 为不同类型的客户提供更多服务

    现在您需要提供比需要更多的服务 . 例如 WebRequestRetrieverMobileRequestRetriever 而不是仅仅访问 IRequestRetriever 并让组合根连接其余部分 .

    如果这个答案能够超越主题(在完成后才实现),请道歉 .

  • 0

    这实际上是一个相当复杂的主题,有许多方法可以实现n层架构 . 没有一种方法是“正确的方式”,你如何做到这一点取决于你的需求和个人喜好 .

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

    事情需要数据,否则你的应用可能没用 . 但是,使您的Address对象加载自身可能不是最好的方法 . 更好的方法可能是工厂类或服务方法 .

相关问题