【问题标题】:In Which assembly the Interface or Abstraction resides?接口或抽象驻留在哪个程序集中?
【发布时间】:2012-06-08 10:36:56
【问题描述】:

在依赖注入中,假设我在 AssemblyA 中有一个 Consumer,在 AssemblyB 中有一个依赖实现。我正在使用 Constructor Injection 以便将依赖项的抽象作为构造函数参数传递给消费者。抽象驻留在哪个程序集中? AssemblyA 或 AssemblyB 或其他一些程序集 (AssemblyC) 以便 AssemblyA 和 AssemblyB 可以引用来自 AssemblyC 的抽象?

【问题讨论】:

    标签: .net dependency-injection


    【解决方案1】:

    据我了解你所拥有的;

    class AssemblyA.ClassA
    {
        public ClassA(ClassB arg) { ... }
    }
    
    abstract class AssemblyB.ClassB
    { }
    
    class AssemblyC.ClassC : AssemblyB.ClassB // some concrete implementation of ClassB
    {  }
    

    那么;

    • ClassB 可以属于 AssemblyA 或 AssemblyB - 在这种情况下,AssemblyA 引用 AssemblyB
    • ClassC 可以属于 AssemblyA、AssemblyB 或 AssemblyC - 在这种情况下,AssemblyA 引用 AssemblyB 和 AssemblyC,AssemblyC 引用 AssemblyB

    这是对您问题的简单化。

    【讨论】:

    • 是的,您通过给出我的意图的代码 sn-p 使我的问题易于理解。实际上,当我对 AssemblyA 进行单元测试时,我不想拖动 AssebmlyX。所以我只是想知道是否可以将抽象保留在单独的程序集中。
    • 是的,如果 ClassA 对 ClassC 没有直接的了解,通过使用接口,那就太好了。减少耦合是一件好事,它会使单元测试更容易。
    【解决方案2】:

    您所问的称为依赖倒置,是 SOLID 原则之一。依赖倒置说你应该依赖抽象而不是实现。它还指出,低层不应该知道高层。

    考虑到这一点,一切都很清楚 =)

    IUserService // abstraction, where should this be placed?
    DbUserService //implementation, placed in YourApp.Core
    UserController(IUserService) // usage, placed in YourApp.UI
    

    嗯。由于较低层(Core)不应该知道较高层(UI),我们不能将界面放置在 UI 项目中。

    所以我们有两个选择:第三个程序集或核心程序集。

    还有另一个原则叫做“Separated Interface”,它规定接口应该放在另一个包/程序集中。

    为了简单起见,我通常将接口和实现放在同一个包中。

    【讨论】:

    • 分离接口在大型项目中特别有用。它允许您减少编译时间、支持并行开发并强制执行架构边界。对于较小的项目来说,这可能是矫枉过正。
    【解决方案3】:

    简答

    抽象(包括接口)属于调用者

    更长的答案

    查看implementations section of the DI wikipedia article

    这显示了两个实现:

    • 抽象属于更高级别的组件
    • 抽象在它们自己的包中

    要理解这一点,重要的是要理解抽象在依赖倒置中试图做什么。目标是让更高级别的流程根据自己的术语定义依赖关系,但让其他人稍后提供实现。这允许高层流程在低层实现发生变化时避免变化,并灵活​​地交换不同的实现。

    如果接口与实现耦合,那么我们就达不到这个目标,因为接口是not an abstraction。接口会随着实现而改变,更高级别的流程不会与变化隔离。

    还要考虑包依赖结构。如果接口属于实现,则高级流程必须引用任何用例的低级包。但是,如果抽象属于高层流,那么我们可以根据不同的用例引用不同的实现。这是Ports and AdaptersClean Architecture 等基础架构。我认为马克西曼describes it well

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-10
      • 2010-12-21
      • 1970-01-01
      • 2015-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-03
      相关资源
      最近更新 更多