0

In my job I work with C# (although the language is irrelevant for my question, and now I'd like to focus on Android) and we usually inject interfaces and not the actual classes, so I was wondering what are the real benefits of that?

As far as I know, I can understand interfaces (if no DI is taking part) as a way of not tying class methods to fixed implementations of their "dependencies", for example, we could decide to change the database engine so, using interfaces, the repository methods could be easily changed adjusting code to the new engine and the services accessing the repository would stay unaltered.

Given that, and please correct me if I'm wrong, I cannot see any real benefits of injecting interfaces. I mean, we already have DI so if we inject we are already decoupling and giving the possibility of altering the dependency as per our needs (injecting one implementation or another) then why injecting interfaces?

9
  • 1
  • 3
    Maybe this is nitpicking but you can't inject an interface. You can only inject an object that implements an interface. I think what you mean to say is that the object receiving the injection depends on the interface and not the concrete implementation. The reason for this is the Liskov Substitution Principle and SOLID.
    – John Wu
    Jul 22 at 20:14
  • You are right @John Whu. Please, put it as an answer and I'll mark it as correct. Jul 22 at 20:36
  • It's a pitty you downvoted me just because there is a similar question @Greg Burghardt. Maybe I missed it when looking for help, or whatever. You could have just put the link without downvoting, but it's your right. Is funny because many times I post great questions and no one upvote, but one question that is considered non appropriate for whatever reason is enough for being downvoted. In the end, this is a perfectly correct question. I'm not asking about how to cook a chicken in the stove. Jul 22 at 20:53
  • The down-vote wasn't me. I do not typically down-vote possible duplicates unless the question looks like someone didn't do any research or put any time into it. I don't think that about your question, though. Jul 22 at 21:10

3 Answers 3

0

Typically we inject objects. But, well, interface injection is actually a thing.

One thing to understand, an interface is different than an interface (the keyword). This confusion is brought to you by the creators of Java who decided they wanted to support multiple inheritance after all and were to lazy/stuck-with-old-code to redesign how an abstract class worked. And so the interface was born.

So if what you're trying to ask is if you have to code against interface rather than a perfectly extendable class then no. You do not have to slap interfaces on everything. Unless you want multiple inheritance to work in those languages that need this hack.

Anyway, that's not an injection. That's what you're coding against.

This is interface injection:

// Service setter interface.
public interface ServiceSetter {
    public void setService(Service service);
}

// Client class
public class Client implements ServiceSetter {
    // Internal reference to the service used by this client.
    private Service service;

    // Set the service that this client is to use.
    @Override
    public void setService(Service service) {
        this.service = service;
    }
}

// Injector class
public class ServiceInjector {
    Set<ServiceSetter> clients;
    public void inject(ServiceSetter client) {
        clients.add(client);
        client.setService(new ServiceFoo());
    }
    public void switchToBar() {
        for (Client client : clients) {
            client.setService(new ServiceBar());
        }
    }
}

// Service classes
public class ServiceFoo implements Service {}
public class ServiceBar implements Service {}

What does that get you? Your dependencies have no idea what their clients are. Will you ever need that? I always value keeping things from knowing things that they don't need to know. Honestly though, I've never had good reason to do this. But it is called interface injection.

6
  • Just stumbled upon this; I might be wrong, but it strikes me that this weirdly named "Interface Injection" thing doesn't really belong to the Wikipedia article on DI - at least, not under the title "Types of dependency injection". Cause, this is not a distinct type of dependency injection, this is just setter injection + some client-side dependency management code around it. Basically, in the code above - the Service classes are the dependencies of the Client (that just uses setter injection), and the Client itself is used by some orchestration code that requires something with a setService Jul 25 at 20:35
  • Aaah, the name comes from this article by Martin Fowler; it's unfortunate that he chose that particular name, I find its confusing when encountered out of context. Jul 25 at 20:48
  • 2
    @FilipMilovanović I'll admit it's an unfortunate name. And I'll be damned if I've ever found it useful. But I read about it and now it's stuck in my brain. Probably where the names of old girl friends should have been. Sigh. Jul 25 at 21:42
  • The description of the pattern/technique on Wikipedia is also very confusing, because their example doesn't actually demonstrate what they are talking about (e.g. where they say "the dependency must do something in addition to simply passing back a reference to itself [... e.g.] reference-counting"). In Fowler's article, the scheme is something like: every abstract dependency comes along with a corresponding injector interface (really, a factory or a provider for the dependency), so that you can dynamically chose/configure what happens at the injection time. 1/2 Jul 25 at 22:07
  • 1
    @FilipMilovanović what truly scares me is someday I may find use for it. And then I’ll have to explain it. Jul 25 at 22:16
0

There's the situation where a class implements an interface and nothing else. However, if you write software for MacOS / iOS, it is very, very common that you implement an interface in a quite unrelated class.

For example, if the user changes the contents of a textfield, you'd want to check if the change is allowed, you'd want to check if they hit the "return" key which might cause some action etc., and you write the code for this not in a textfield, but in a class which controls the textfield (and other fields). So an interface is declared by the TextField class, it is implemented by a quite unrelated class, and an instance of that class injected into a TextField instance to handle user interactions.

In the TextField class, you most definitely want an interface (for example because you have no idea whatsoever which class is going to implement it). And it's quite likely that you inject a concrete class instance. And that you have a dozen other classes that are injected into other TextField instances.

0

The payoff comes when you start testing. Typically you create concrete classes with very limited functionality that implement the interface. For instance a dummy repository class may be coded to return a known values for it's getPasswordHash(userId) method. This allows testing the calling code without a backing database.

A second situation where an interface is highly desirable is when you write a library class that requires a callback method from the library user. It is easy to inject a dependency that implements your interface but much harder to have the caller supply a concrete class that extends your concrete class. Many OO languages do not support multiple inheritance, so don't use up the one chance at inheritance when there is a good alternative.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.