使类依赖项出现在接口中而不是属性

时间:2012-02-21 11:53:34

标签: c# .net oop interface

我有一个接口和一个实现该接口的类。

我要求该类依赖于ITimer。创建一个私有成员并传入一个构造函数参数,并将私有成员分配给该构造函数参数。

如何使界面以某种方式声明此ITimer但不作为属性?它不像我不能正确测试MyClass,但我认为接口应该是一个类必须遵守的契约,因此我的类有一个依赖,所以如何使它出现在界面中?

public interface IMyInterface
{
  void DoSomething();
}

public class MyClass : IMyInterface
{
  private ITimer MyTimer;

  public MyClass(ITimer timer)
  {
    MyTimer = timer;
  }

  public void DoSomething()
  {

  }
}

6 个答案:

答案 0 :(得分:3)

这不起作用,并且很好,它不起作用:

您对ITimer的依赖不是界面的一部分,它是界面的实施的一部分 - 因此将此隐藏在界面中是是对的。

如果界面的所有实现都需要依赖ITimer(如果是这样的话,),那么你的接口声明应该附加在那里。

答案 1 :(得分:3)

使用C#中的接口无法做到这一点。你可以做的是继承一个接口的抽象类instread。

public abstract class AMyClass
{
  protected ITimer MyTimer;

  public AMyClass(ITimer timer)
  {
    MyTimer = timer;
  }

  public abstract void DoSomething();
}

public class MyClass : AMyClass
{
  public override void DoSomething()
  {

  }
}

答案 2 :(得分:2)

如果您在接口上明确不想要ITimer之类的依赖项,那么它听起来就像是一个实现细节,所以正确它不是定义为合同的一部分。一种方法是“忘记ITimer;只有一些实现可能需要它,这是IoC / DI解析器的关注点。”

显然,构造函数不是界面的一部分。我能想到的另一件事(在保持IMyInterface关闭API的同时)是拥有IMyInterfaceFactory接口,Create方法需要ITimer - 但是然后强制执行特定的依赖项集,这可能无法反映实际的实现。

如果以上套件都没有,而ITimer 基本上是界面的一部分,我会将其正式作为界面的一部分。

答案 3 :(得分:2)

为什么财产不合适?你可以拥有一个带私人二手的房产,它可以完全满足您的需求。

其他选项是从带有受保护Timer的抽象基类派生,并同时实现接口。

理论上依赖注入是您正在寻找的。因此,可能需要了解Inversion of Control容器可能值得花时间。

答案 4 :(得分:1)

接口是类暴露的功能的合约。如果界面中没有ITimer的自然位置,那么它在实现它的特定类中看起​​来像实现细节,因此应保留在类中。

答案 5 :(得分:0)

如果某个类可以在不使用ITimer的情况下实现您的界面,那么它是否不符合该界面?这显然是。

使用ITimer是一个实现细节,因此不应在界面中表示。