I've been contemplating how to balance testable design using dependency injection with providing simple fixed public API. My dilemma is: people would want to do something like var server = new Server(){ ... } and not have to worry about creating the many dependencies and graph of dependencies that a Server(,,,,,,) may have. While developing, I don't worry too much, as I use an IoC/DI framework to handle all that (I'm not using the lifecycle management aspects of any container, which would complicate things further).

Now, the dependencies are unlikely to be re-implemented. Componentisation in this case is almost purely for testability (and decent design!) rather than creating seams for extension, etc. People will 99.999% of the time wish to use a default configuration. So. I could hardcode the dependencies. Don't want to do that, we lose our testing! I could provide a default constructor with hard-coded dependencies and one which takes dependencies. That's... messy, and likely to be confusing, but viable. I could make the dependency receiving constructor internal and make my unit tests a friend assembly (assuming C#), which tidies the public API but leaves a nasty hidden trap lurking for maintenance. Having two constructors which are implicitly connected rather than explicitly would be bad design in general in my book.

At the moment that's about the least evil I can think of. Opinions? Wisdom?

5 Answers 5


Dependency injection is a powerful pattern when used well, but all too often its practitioners become dependent on some external framework. The resulting API is quite painful for those of us who don't want to loosely tie our app together with XML duct tape. Don't forget about Plain Old Objects (POO).

First consider how you would expect someone to use your API--without the framework involved.

  • How do you instantiate the Server?
  • How do you extend the Server?
  • What do you want to expose in the external API?
  • What do you want to hide in the external API?

I like the idea of providing default implementations for your components, and the fact that you have those components. The following approach is a perfectly valid, and decent OO practice:

public Server() 
    : this(new HttpListener(80), new HttpResponder())

public Server(Listener listener, Responder responder)
    // ...

As long as you document what the default implementations for the components are in the API docs, and provide one constructor that performs all the setup, you should be fine. The cascading constructors are not fragile as long as the set up code happens in one master constructor.

Essentially, all the publicly facing constructors would have the different combinations of components you want to expose. Internally, they would populate the defaults and defer to a private constructor that completes the setup. In essence, this provides you some DRY and is pretty easy to test.

If you need to provide friend access to your tests to set up the Server object to isolate it for testing, go for it. It won't be part of the public API, which is what you want to be careful with.

Just be kind to your API consumers and don't require a IoC/DI framework to use your library. To get a feel for the pain you are inflicting make sure your unit tests don't rely on the IoC/DI framework either. (It's a personal pet peeve, but as soon as you introduce the framework it's no longer unit testing--it becomes integration testing).

  • I agree, and I'm certainly no fan of IoC config soup - XML configuration is not something I use at all where IoC is concerned. Certainly requiring IoC usage is exactly what I was avoiding - it's the kind of assumption a public API designer can never make. Thanks for the comment, it's along the lines that I was thinking and it's reassuring to have a sanity check now and again!
    – kolektiv
    Jan 5, 2011 at 10:37
  • -1 This answer basically says "don't use dependency injection" and contains inaccurate assumptions. In your example if the HttpListener constructor changes then the Server class must also change. They're coupled. A better solution is what @Winston Ewert says below, which is to provide a default class with dependencies pre-specified, outside of the library's API. Then the programmer is not forced to set up all the dependencies since you make the decision for him, but he still has the flexibility to change them later on. This is a big deal when you have third-party dependencies. Mar 22, 2013 at 15:27
  • FWIW the provided example is called "bastard injection". stackoverflow.com/q/2045904/111327 stackoverflow.com/q/6733667/111327 Mar 22, 2013 at 15:33
  • 1
    @MichaelDudley, did you read the OP's question. All "assumptions" were based on the OP's provided information. For a time, the "bastard injection" as you called it, was the favored dependency injection format--particularly for systems whose compositions don't change during runtime. Setters and getters are also another form of dependency injection. I simply used examples based on what the OP provided. Mar 22, 2013 at 15:38

In Java in such cases it's usual to have a "default" configuration built by a factory, kept independent from the actual "properly" behaving server. So, your user writes:

var server = DefaultServer.create();

while the Server's constructor still accepts all its dependencies and can be used for deep customization.

  • +1, SRP. A dentist office's responsibility is not to build a dentist's office. A server's responsibility is not to build a server.
    – R. Schmitz
    Jul 3, 2019 at 11:38

How about providing a subclass which provides the "public api"

class StandardServer : Server
    public StandardServer():
        this( depends1, depends2, depends3)

The user cannew StandardServer()and be on their way. They can also use the Server base class if they want more control over how the server functions. This is more or less the approach I use. (I don't use a framework as I haven't yet seen the point.)

This still exposes the internal api, but I think you should. You've split up your objects into different useful components which should work independently. There is no telling when a third party might want to use one of the components in isolation.


I could make the dependency receiving constructor internal and make my unit tests a friend assembly (assuming C#), which tidies the public API but leaves a nasty hidden trap lurking for maintenance.

That doesn't seem like a "nasty hidden trap" to me. The public constructor should just be calling the internal one with the "default" dependencies. As long as it's clear that the public constructor shouldn't be modified, everything should be fine.


I totally agree with your opinion. We don't want to pollute component usage boundary just for the purpose of unit testing. This is the whole problem of DI based testing solution.

I would suggest to use InjectableFactory / InjectableInstance pattern. InjectableInstance are a simple reusable utility classes which are mutable value holder. The component interface contains a reference to this value holder which initialized with default implementation. The interface will provide a singleton method get() which delegate to the the value holder. The component client will call the get() method instead of new to get an instance of implementation to avoid direct dependency. During testing time, we can optionally replace the default implementation with a mock. Following I will use one example TimeProvider class which is an abstraction of Date() so it allows unit testing to inject and mock to simulate different moment. Sorry I'll use java here as I'm more familiar with java. C# should be similar.

public interface TimeProvider {
  // A mutable value holder with default implementation
  InjectableInstance<TimeProvider> instance = InjectableInstance.of(Impl.class);  
  static TimeProvider get() { return instance.get(); }  // Singleton method.

  class Impl implements TimeProvider {        // Default implementation                                    
    @Override public Date getDate() { return new Date(); }
    @Override public long getTimeMillis() { return System.currentTimeMillis(); }

  class Mock implements TimeProvider {   // Mock implemention
    @Setter @Getter long timeMillis = System.currentTimeMillis();
    @Override public Date getDate() { return new Date(timeMillis); }
    public void add(long offset) { timeMillis += offset; }

  Date getDate();
  long getTimeMillis();

// The client of TimeProvider
Order order = new Order().setCreationDate(TimeProvider.get().getDate()));

// In the unit testing
TimeProvider.Mock timeMock = new TimeProvider.Mock();
TimeProvider.instance.setInstance(timeMock);  // Inject mock implementation

The InjectableInstance is pretty easy to implement, I have a reference implementation in java. For the details, please refer to my blog post Dependency Indirection with Injectable Factory

  • So... you replace dependency injection with a mutable singleton? That sounds horrible, how would you run independent tests? Do you open a new process for each test or force them into a specific sequence? Java is not my strong suit, did I misunderstand something?
    – nvoigt
    Jul 4, 2019 at 15:29
  • In Java maven project, the shared instance is not a problem as junit engine will run each test in different class loader by default, However I do encounter this problem in some IDE as it may reuse the same class loader. To solve this problem, the class provides a reset method to be called to reset to original state after each test. In practise, it's a rare situation that different test want to use different mock. We have applied this pattern for large scale projects for years, Everything just run smoothly, we enjoyed readable, clean code without sacrifice portability and testability. Jul 5, 2019 at 18:10

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