Alternative solution:
If your container is able to validate its own configuration, you can write an integration test for that.
That's not really compile time checking, but if it's part of your test suite, you'll still notice missing dependencies quickly.
Of course it only works when all your dependencies are known at compile time.
Here's an example from a recent project of mine, which uses SimpleInjector.
SimpleInjector has a Verify()
method, which tries to resolve all registered dependencies.
I'm using SimpleInjector like this:
public class Bootstrapper
{
public static Container BuildContainer()
{
var container = new Container();
container.Register<IFoo, Foo>();
container.Register<IBar, Bar>();
// etc.
container.Verify();
return container;
}
}
public class Program
{
public static void Main(string[] args)
{
var container = Bootstrapper.BuildContainer();
container.GetInstance<IFoo>().Run();
}
}
Verify
will throw an exception when anything goes wrong, so the app would crash at runtime.
To check this while running my test suite, I wrote the following test (xUnit.net syntax):
public class BootstrapperTests
{
[Fact]
public void DependenciesWereResolved()
{
bool error = false;
try
{
var container = Bootstrapper.BuildContainer();
}
catch (InvalidOperationException)
{
error = true;
}
Assert.False(error);
}
}
Note: xUnit.net doesn't have anything like Assert.DidNotThrow<Exception>
, that's why I needed to catch the exception and set the error
variable.