Given the (old) debate over whether Singletons are overused/abused/are worth it - would it be a bad idea to inject the dependencies as default parameters? In this way, we could get rid of defining singletons for the dependency container registry for the corresponding interfaces - while still leaving the objects in question testable - all one needs to do is to explicitly inject a mock as the dependency when Unit Testing such classes.
Example:
public class Foo
{
IDoSomething x;
Foo(IDoSomething x = null)
{
this.x = x ?? new DoSomething()
}
}
public class DoSomething : IDoSomething
{
...
}
in Program.cs
services.AddSingleton(IDoSomething, DoSometing);
This way I am rid of holding singletons throughout my app, without losing testability.
public class FooTests
{
Foo SUT;
Mock<Foo> FooMock;
FooTests()
{
FooMock = new Mock<Foo>();
FooMock.Setup(...);
SUT = new Foo(FooMock.Object);
}
}
Giving it a second thought, if I require a singleton (if I need to assure no 2 instances exist for this object) than it's more like a matter of defining the lifetime of that instance (singleton, scoped, transaction). In other words, there should be nothing wrong in injecting a dependency as a mandatory parameter - and properly registering the instantiation type at the dependency container.
DoSomething
constructor itself wants some arguments?Foo
andDoSomething
classes, which is what theIDoSomething
interface is intended to solve. If you absolutely need a way to tie those two classes together, introduce a third mediator class (sometimes implemented as a factory).