Zdarzało wam się skończyć kodzić feature w aplikacji webowej, z wszystkimi testami, clean code i w ogóle..
A jednak przy pierwszym odpaleniu BANG! Cała aplikacja zdycha?
Na pewno większość developerów zderzyła się z podobnym wyjątkiem:
“No matching bindings are available, and the type is not self-bindable.” (Ninject)
Dependency Injection Container
Oczywiście winą jest źle skonfigurowany kontener zależności (Autofac, Ninject czy inny StructureMap).
Nie jest to jakiś duży problem, wystarczy poprawić kilka bindingów i po kłopocie.
Ale niesmak pozostaje, zawsze trzeba pamiętać aby ten binding dodać/poprawić przy zmianie kodu.
A jak wiemy programiści lubią zapominać…
Testowanie kontenera
Warto napisać sobie jeden mały test który sprawdza czy wszystkie controllery mogą być poprawnie utworzone przez kontener:
[Test]
public void AllDependenciesAreCorrectlyWired()
{
HttpContext.Current = new HttpContext(
new HttpRequest("", "http://tempuri.org", ""),
new HttpResponse(new StringWriter()));
var kernel = IoC.CreateKernel();
var mvcAssembly = typeof(IoC).Assembly;
var controllerTypes = mvcAssembly.GetExportedTypes()
.Where(type => typeof(IHttpController).IsAssignableFrom(type))
.Where(type => !type.IsAbstract)
.Where(type => !type.IsGenericTypeDefinition)
.ToArray();
foreach (var controllerType in controllerTypes)
{
var constructors = controllerType.GetConstructors().Where(x => x.IsPublic).ToList();
Check.That(constructors).HasSize(1);
Check.ThatCode(() => constructors.Single()
.GetParameters()
.Select(x => x.ParameterType)
.Select(x => kernel.Get(x))
.ToList())
.DoesNotThrow();
}
}
Jeden niuans: jak znaleźć assembly z wszystkimi controllerami?
Ja akurat używam klasy w której trzymam bindingi Ninjecta – IoC.
Szczególnie ważne jest to gdy współdzielimy kod między aplikacją webową a dowolną inną.
Zmiany współdzieloncyh klas mogą wykrzaczyć kontener webowy.
I najprawdopodobniej, nie zostanie on sprawdzony przy implementowaniu funkcjonalności do aplikacji desktopowej.

Be First to Comment