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