【问题标题】:c# dependency injection with interfaces and hiding internalc# 带接口的依赖注入和隐藏内部
【发布时间】:2013-12-08 06:22:54
【问题描述】:

我正在尝试重构项目中的一些类,以使用接口和依赖注入使它们可测试。但我遇到以下问题:

public interface IInterfaceA 
{
   void SomePublicMethod();
}

public class ConcreteObject : IInterfaceA
{
   public void SomePublicMethod() { ... }
   public void SomeOhterMethod() { ... }
   public void YetAnotherMethod() { ... }
}

public class AnotherConcreteObject 
{
    private IInterfaceA _myDependency;
    public AnotherConcreteObject( IInterfaceA myDependency )
    {
       _myDependency=myDependency;
    }
}

到目前为止,一切都很好,非常标准的代码。 AnotherConcreteObject 需要调用 SomeOtherMethod,但我不希望其他类(例如在不同的程序集中)能够调用 SomeOtherMethod。所以外部 SomePublicMethod 应该是可见的,但 SomeOtherMethod 不应该是可见的。只有 AnotherConcreteObject 的实例才能调用 SomeOtherMethod。 SomeOtherMethod 将例如设置一个内部属性,稍后由 YetAnotherMethod 使用该属性来确定应该发生什么。在所有其他情况下,内部属性设置为默认值,例如当从其他任何类调用 YetAnotherMethod 时,AnotherConcretObject 除外。

当不使用接口时,这是可能的,因为 AnotherConcreteObject 与 ConcreteObject 在同一个程序集中,因此它可以访问内部属性和方法。不同程序集中的类无法设置该属性或调用该方法,因为它们无权访问内部属性和方法。

【问题讨论】:

  • 如果AnotherConcreteObject 需要调用不在公共接口中的东西,那么它应该依赖于ConcreteObject 而不是接口——或者可能是另一个暴露SomeOtherMethod 的接口。跨度>
  • 但是如果 AnotherConcreteObject 直接依赖于 Concrete 对象,这不是让 AnotherConcreteObject 更难(或不可能)测试吗?我希望 AnotherConcreteObject 可以使用模拟进行测试
  • 您是否在测试 AnotherConcreteObject 时遇到问题,因为 AnotherConcreteObject 的实例调用了设置内部属性的 SomeOtherMethod?
  • 我刚刚开始研究如何对接口进行建模,以便使我的类更易于测试,因此我还没有编写任何测试。我参加了有关使用模拟框架的课程,并了解了接口的重要性。所以现在我正在寻找一种在这种情况下为我的界面建模的方法。
  • 这就是为什么我建议使用另一个暴露SomeOtherMethod的接口。例如,它可能是扩展IInterfaceA 的接口。

标签: c# interface dependency-injection


【解决方案1】:

有几种可能的解决方案,具体取决于您在做什么:

1 如果SomePublicMethod 是公共的,但SomeOtherMethod 是内部的,那么不要将它们放在同一个类中,它们可能会做非常不同的事情,因此可以发挥关注点分离原则。 2 如果ConcreteObject 没有状态并且不会引起副作用,或者如果您不打算对它并行运行测试,即具有单元行为,那么它可能不需要模拟,所以直接访问它。

【讨论】:

  • SomeOtherMethod 和 SomePublicMethod 应该在同一个类中,因为 SometOtherMethod 会影响该类在其他部分的行为。
  • @rekna 如果这两个方法必须在同一个类中,那么我会质疑为什么一个是内部的而另一个是公共的。这可能表明该课程做得太多。
  • 假设两个方法配置/设置类,而第三种方法执行类的主要功能。这些方法会影响此主要功能的控制流。
猜你喜欢
  • 1970-01-01
  • 2018-09-02
  • 1970-01-01
  • 2017-06-10
  • 2012-03-15
  • 2010-10-06
  • 1970-01-01
  • 2023-01-19
相关资源
最近更新 更多