Dependency Injection and Explicit Interface Implementation
Asked Answered
T

3

9

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();
    }
}
Tamberg answered 28/7, 2015 at 11:17 Comment(2)
Could you update your code to use IFoo instead of Foo? It's confusing in my opinion...Defrock
Done - sorry, usually I respect code conventions...Tamberg
P
8

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.

Podium answered 28/7, 2015 at 11:36 Comment(2)
That's what I was trying to get at. If for some obscure reason one didn't pay attention and wrote a constructor expecting a concrete class: public Baz(Foo1 foo), the use of explicit interface implementations would forbid any calls to the object's methods. Trying to cast around a concrete implementation to its interface would ring some alarm bells, then, wouldn't it?Tamberg
If you accidentally add a constructor expecting the concrete class, then you've just lost the decoupling that's the purpose of Dependency Injection. That's a much bigger problem with the service, and should be solved at the root of the problem, instead of patched by some arbitrary client.Podium
A
1

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.

Apparatus answered 28/7, 2015 at 11:35 Comment(0)
D
0

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)

Defrock answered 28/7, 2015 at 11:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.