Z poprzedniego posta “DI: profesjonalne kontenery” wiemy, że wykorzystujemy kontener. A także, że użycie własnej implementacji to głupota. Pomyśleliśmy również jakimi nad kryteriami wyboru kontenera do naszego projektu.
Tak jak napisałem: ja używam Autofac. I właśnie ta biblioteka wyląduje w przedstawianym demo.
Pierwsze co robię to:
Install-Package Autofac
Mając na pokładzie Autofaca mogę z niego korzystać, zapominając o swoim PoorMansContainer. Autofac jest o tyle ciekawy, że bardzo mocno separuje dwie “fazy” działania kontenera: konfigurację i dostarczanie instancji. Separuje je tak mocno, że do konfiguracji wykorzystuje się osobną, dedykowaną klasę: ContainerBuilder. Konfiguracja w omawianym demie wygląda tak:
static void Main() { var builder = new ContainerBuilder(); Assembly executingAssembly = Assembly.GetExecutingAssembly(); builder.RegisterAssemblyTypes(executingAssembly) .AsSelf() .AsImplementedInterfaces(); // override default registration if needed builder.RegisterType<EmailValidator>() .AsImplementedInterfaces() .SingleInstance(); _container = builder.Build(); }
https://github.com/maniserowicz/di-talk/blob/demo5-start/src/app/WebServer.cs
Widzimy tutaj dwie opcje, których nie posiadał mój własny kontener: automatyczną rejestrację wszystkich klas w aktualnym assembly (RegisterAssemblyTypes) oraz konfigurację EmailValidatora jako Singleton. Proste? Proste. A jakie potężne.
Dodatkowo Autofac oczywiście potrafi po sobie posprzątać:
static void Shutdown() { _container.Dispose(); }
A jak wygląda tworzenie kontrolera? O dziwo, identycznie jak u mnie!
public void RegisterUser(string email) { var controller = _container.Resolve<UsersController>(); controller.RegisterUser(email); }
Ba, mało tego! Nigdzie indziej w całej aplikacji nie zmieniło się NIC! To dzięki zastosowaniu się do “3 calls pattern”, o którym już pisałem (i o którym jeszcze napiszę). Aplikacja ma głęboko gdzieś czy jej kontrolery są rzeźbione mymi rencami pienknymi, czy też przez kontener tworzone “like a pro”.
Oczywiście to co zobaczyliśmy wyżej to jedynie romantyczne liźnięcie możliwości Autofaca samym czubem ozora. Potrafi on o wiele więcej, na przykład rozbić konfigurację kontenera na osobne, “reużywalne” klasy (moduły). Wspiera też interceptory, dzięki czemu możemy pobawić się w AOP bez “tkania” kodu (code weaving) na etapie kompilacji. Ładnie integruje się też na przykład z ASP.NET MVC i kilkoma innymi frameworkami. Ale nie ma sensu, abym to wszystko przepisywał i tłumaczył z angielskiego, odsyłam do bardzo dobrej dokumentacji: https://github.com/autofac/Autofac/wiki.
Jeszcze jedno małe wtrącenie na koniec: na jednym z moich występów zwrócono mi uwagę, że nie mówi się “ałtofak” tylko “ałtofejk”. Nie mogłem wprost w to uwierzyć, więc zapytałem autora, Nicholasa. Okazało się, że przez cały czas mówiłem poprawnie. Żeby jednak nie było wątpliwości i aby poprawna wymowa utkwiła w pamięci narysowałem kalambur utrwalający ten jakże potrzebny w cywilizowanym świecie fakt:
To tyle jeśli chodzi o Autofac. Wiem, przedstawiłem bardzo podstawowe jego zastosowanie, ale być może w przyszłości urodzi się coś bardziej zaawansowanego. Póki co: do następnego razu, kiedy to nadejdzie pora na kilka finalnych refleksji!