„Ty, który wchodzisz, żegnaj się z nadzieją” – rzecz o NuGetowych grzechach

W kilku ostatnich notkach prezentowałem Wam narzędzia i biblioteki, które ułatwiają tworzenie lub porządkują kod pisanej aplikacji. Podobnie miało być i w tym wpisie – będzie jednak o problemie, który stanął mi na drodze.

Jednym z założeń opisanych przeze mnie było korzystanie ze wzorca Inversion of Control podczas projektowania i tworzenia elementów aplikacji. Jako, że bynajmniej nie czuję się na siłach, by napisać własny kontener IoC – chciałem użyć popularnego Autofaca.

Chcemy Autofaca – nic prostszego! Tools -> NuGet Packet Manager -> Manage NuGet Packages fo Solution i wyszukujemy Autofac… Jest! Wersja 4.0.0, instalujemy… Udało się.

Teraz konfiguracja – poniższy kod opiszę w następnej notce, która będzie właściwym wprowadzeniem do korzystania z Autofaca. W tej chwili musimy wiedzieć tylko tyle, że najprostsza konfiguracja Autofaca wygląda tak:

var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

i wrzucamy ją do metody Application_Start() w pliku Global.asax.cs – który jest plikiem startowym aplikacji Mvc. Próba kompilacji zakończy się jednak błedem – brakuje nam pakietu Autofac.Mvc5, który zawiera klasę DependencyResolver i inne elementy integracji Autofaca z ASP.NET Mvc. Wyszukujemy więc potrzebny pakiet NuGetem – jest wersja 3.3.4, instalujemy, kompilujemy – tym razem pomyślnie i próbujemy uruchomić aplikację. Niestety – efekt jest bardzo daleki od oczekiwań:

009a

O co chodzi? Próby znalezienia informacji o takim zachowaniu nie dają dobrych rezultatów… Sam komunikat sugeruje jakieś problemy z metodą Autofac.Integration.Mvc.RequestLifetimeScopeProvider oraz interfejsem Autofac.ILifetimeScope oraz różnicami w określeniu zabezpieczeń tych dwóch elementów…

Ok. Sprawdźmy, jak sytuacja będzie wyglądać na świeżutkiej i pustej aplikacji Mvc – tworzymy zatem nowy projekt, dodajemy pakiet Autofac i Autofac.Mvc5 oraz kod konfiguracji… i dostajemy taki sam błąd! :-(

Po dłuuugiej chwili gorączkowego googlania pojawia się promyk nadziei – w kilku miejscach w internecie  pojawiają się opisy podobnych problemów z innymi bibliotekami, a rozwiązania sugerują aktualizację tych czy innych pakietów. Ok – wracamy do NuGeta. Pierwsza myśl: może błąd powoduje wybrana opcja ‚Include prerelease’ oznaczająca wyświetlanie również wersji beta pakietów. Zmieniamy na ‚Stable only’:

009b

Usuwam więc oba pakiety Autofaca i dodaję je raz jeszcze – tym razem Autofac w wersji 3.5.2, a Autofac.Mvc5 znów 3.3.4. Kompilacja, uruchomienie i… Sukces! Aplikacja uruchamia się, a po dodatkowych testach widzę, że Autofac działa poprawnie.

No dobrze, powie ktoś. Po prostu nie instaluj pakietów w wersji prerelease. Racja. I może, skoro Autofac.Mvc5 zależy od Autofac – to zainstaluj najpierw Autofac.Mvc5 i niech sobie dogra potrzebne pakiety – w zgodnych wersjach. Tak spróbowałem – wgrany został Autofac.Mvc5 w wersji 3.3.4 i Autofac w wersji 3.4.0. Dlaczego Autofac nie w wersji 3.5.2 (najwyższej stabilnej)? NuGet dość specyficznie wybiera wersje pakietów zależności – więcej o tym tu.

Niemniej – mamy potrzebne pakiety w stabilnych wersjach. Czy zadziałało? Prawie :-) :

009c

W tym momencie przypomniały mi się stare czasy z piekłem zależności pakietów w dystrybucjach Linuxa. Złe czasy…

I jeszcze jeden kamyczek do ogródka: NuGet pozwala na określenie dla pakietów, od których dany pakiet zależy, zakresu dozwolonych wersji. Dla pakietu Autofac.Mvc5 w wersji 3.3.4 jego zależność Autofac jest dozwolona w wersjach od 3.4.0 (włącznie) do 4.0.0 (ale bez 4.0.0) Dlaczego zatem w pierwszej próbie instalacji NuGet doinstalował do Autofaca 4.0.0 nowy pakiet Autofac.Mvc4 w wersji 3.3.4 nie krzycząc o niespełnionych/złamanych zależnościach? Nie znalazłem na to odpowiedzi.

Wróciłem więc do działającego zestawu Autofaca 3.5.2 i Autofac.Mvc5 3.3.4 i problem wydaje się rozwiązany. W przyszłości będę jednak bardziej sceptyczny odnośnie NuGeta – pamiętajcie: Kontrola najwyższą formą zaufania! :-)

 

Marcin

Dodaj komentarz