Jon
Jon

Reputation: 40062

Make a class dependency appear in interface without it being a property

I have an interface and a class that implements that interface.

I have a requirement that the class has a dependency on ITimer. A private member is created and a constructor argument is passed in and the private member is assigned to that constructor parameter.

How do I make it so that the interface has this ITimer declared somehow but not as a property? Its not as if I can't test MyClass properly but I thought the interface was supposed to be a contract that the class must adhere to therefore my class has a dependency so how do I make this appear in the interface?

public interface IMyInterface
{
  void DoSomething();
}

public class MyClass : IMyInterface
{
  private ITimer MyTimer;

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

  public void DoSomething()
  {

  }
}

Upvotes: 1

Views: 211

Answers (6)

Marc Gravell
Marc Gravell

Reputation: 1063844

If you have a dependency such as ITimer that you explicitly don't want on the interface, then it sounds like an implementation detail, so it is correct that it isn't defined as part of the contract. One approach is "forget about ITimer; only some implementations might need it, and that is the concern of an IoC/DI resolver".

Constructors are not part of the interface, obviously. The only other thing I can think of (while keeping IMyInterface off the API) is to have an IMyInterfaceFactory interface, with a Create method that takes an ITimer - but that is then forcing a particular set of dependencies, which may not reflect the actual implementations.

If none of the above suite, and ITimer is essentially part of the interface, I'd make it formally part of the interface.

Upvotes: 2

Yurii Hohan
Yurii Hohan

Reputation: 4171

Why is property not appropriate? You can have a property with a private setter which does exactly what you need, it seems.

Other option is to derive both from an abstract base class with protected Timer and implement the interface at the same time.

Theoretically Dependency Injection is what you are looking for. So may be having a look at Inversion of Control containers might be worth the time.

Upvotes: 2

Adi Lester
Adi Lester

Reputation: 25211

If a class can implement your interface without using ITimer, does it not adhere to the interface? It obviously does.

The use of ITimer is an implementation detail, and so it shouldn't be represented in the interface.

Upvotes: 0

Jordão
Jordão

Reputation: 56507

An interface is a contract to a capability that a class exposes. If there's no natural place for ITimer in the interface, then it looks like an implementation detail in a specific class that implements it, and as such, should remain in the class.

Upvotes: 1

A. Tapper
A. Tapper

Reputation: 1271

This cannot be done with an interface in C#. What you could do is to inherit from an abstract class instread of an interface.

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()
  {

  }
}

Upvotes: 3

Eugen Rieck
Eugen Rieck

Reputation: 65314

This will not work, and it is good, that it will not work:

Your dependency on ITimer is not part of the interface, it is part of your implementation of the interface - so having this hidden from the interface is the right thing.

If ALL implementations of the interface need a dependency on ITimer (and only if so), then your interface declaration should be appended to care for that.

Upvotes: 3

Related Questions