Reputation: 3580
Is there a benefit implementing interfaces explicitly with respect to Dependency Injection?
As far as I understand, interfaces can be implemented either explicitly or implicitly:
interface IFoo
{
void Bar();
}
//implicit implementation
class Foo1 : IFoo
{
public void Bar(){}
}
//explicit implementation
class Foo2 : IFoo
{
void IFoo.Bar(){}
}
Now the explicit implementation can only be called by calling the interface method, while the implicit implementation can be called directly on an instance of the class:
class Baz
{
void Ba()
{
Foo1 foo1 = new Foo1();
foo1.Bar();
Foo2 foo2 = new Foo2();
foo2.Bar(); //syntax error
IFoo foo2_explicit = new Foo2();
foo2_explicit.Bar();
}
}
Thus, using explicit interface implementations, one cannot accidentally call a method on a concrete class, but one has to call the interface method. Does this prevent tightly coupled code as is one purpose of DI or am I barking up the wrong tree here? After all, one cannot accidently write a constructor or method that gets a concrete class injected instead of an interface:
class Baz
{
void Ba(Foo2 foo)
{
foo.Bar(); //syntax error
}
void Bb(IFoo foo)
{
foo.Bar();
}
}
Upvotes: 9
Views: 3726
Reputation:
In my opinion, in general one should always keep a reference to an object whose type is "just enough" to use. Consider the following example:
public interface IDo
{
void Do();
}
public interface IWatch
{
void Watch();
}
public class Foo : IDo, IWatch
{
public void Dummy() { }
public void Watch() { }
public void Do() { }
}
and then:
//I only want to use Do()
IDo aFoo = new Foo();
//I only want to use Watch()
IWatch bFoo = new Foo();
//I want to use stuff from Foo and optionally stuff from IDo or IWatch
Foo cFoo = new Foo();
When it comes to using dependency injection containers like MEF or Unity you should use an interface to export an object into the container and import it with the same interface type.
Following these patterns I don't really see a benefit in using explicit interface implementations. (It also makes locating your implementation methods more difficult in the standard Visual Studio comboboxes above your text editor)
Upvotes: 0
Reputation: 233125
Normally, the purpose of Dependency Injection is decoupling, which you achieve by injecting the abstraction into its client:
public class Baz
{
private readonly IFoo foo;
public Baz(IFoo foo)
{
this.foo = foo;
}
// Members using this.foo go here...
}
This ensures that Baz
depends on IFoo
, and is decoupled from any concrete implementation.
Whether or not a concrete class implements IFoo
implicitly or explicitly makes no difference.
Once in a while, a class may have a Concrete Dependency, but this isn't particularly normal; and when it happens, the concrete dependency is concrete, so often will not implement an interface at all. Explicit versus implicit interface implementation is irrelevant in such cases.
Upvotes: 8
Reputation: 1009
If your class is in container, then you use interface. So, there are no benefits.
But, if you use your class directly (in tests for example) you have to cast to access the method and it is not convenient.
Total: 0 advantages when you use class in container and bad for tests.
Upvotes: 1