Wstrzykiwanie zależności z Lazy

Wstrzykiwanie zależności z wykorzystaniem kontenerów jest bardzo wygodne, ale niesie też za sobą trochę problemów. Jednym z nich jest liczba oraz moment tworzenia obiektów. W tym wpisie pokażę ten problem oraz zaproponuję swoje rozwiązanie: wstrzykiwanie zależności z Lazy.

Problem

Poniżej przedstawiony jest dość standardowy kawałek kodu aplikacji ASP.NET MVC, w której wykorzystałem wstrzykiwanie zależności przez konstruktor w formie interfejsów.

Jak widać w powyższym kodzie, kontroler w konstruktorze otrzymuje zależność do logiki biznesowej. Logika biznesowa następnie posiada zależność do repozytorium oraz walidatora, a repozytorium posiada jeszcze zależność do DataContext z entity framework.

Domyślnie kontenery działają w ten sposób, że przed utworzeniem instancji jakieś klasy, tworzą instancje klasy zależnej i tak dalej. W związku z tym w naszym przykładzie przed utworzeniem instancji kontrolera utworzone zostaną instancje logiki biznesowej, walidatora, repozytorium oraz kontekst Entity Framework. To wszystko zostanie utworzone za każdym razem, niezależnie od tego, czy obiekty będą używane, czy nie.

W niektórych sytuacjach takie zachowanie jest niepożądane. Wystarczy spojrzeć na akcję Create z kontrolera, która wyświetla tylko formularz, nie korzystając z logiki biznesowej. W tej sytuacji tworzenie tych wszystkich obiektów jest zbędne i niepotrzebnie obciąża działanie aplikacji – w tym przypadku serwera WWW, który mógłby obsłużyć dużo większy ruch.

Widziałem jedną aplikację WPF, która podczas startu (łącznie około 2,5 minuty) tworzyła instancje wszystkich widoków, nawet tych, których użytkownik w ogóle nie mógł widzieć z racji uprawnień. Użycie obiektów Lazy, o których opowiem niżej, spowodowało, że start aplikacji skrócił się do około 30 sekund.

Na potwierdzenie poniżej znajduje się log z testowej aplikacji, który wyświetla informacje o tworzonych obiektach przez kontener (użyłem Autofac) oraz o wywołaniach samych metod.

Darmowy kurs Visual Studio

Pracując z setkami programistów, zauważyłem, że większość osób nie pracuje efektywnie w Visual Studio. W skrajnych przypadkach korzystali z kopiowania z wykorzystaniem menu Edit. Wiem, że to dziwne, ale naprawdę niektórzy tak pracują. Dlatego postanowiłem stworzyć kurs Visual Studio – aby pomóc koleżankom i kolegom w efektywniejszej pracy.

Przygotowałem 20 lekcji e-mail, w których pokażę Ci, w jaki sposób pracować efektywniej i szybciej w Visual Studio. Poznasz dodatki, bez których nie wyobrażam sobie pracy w tym IDE.

Po więcej informacji zapraszam na dedykowaną stronę kursu: Darmowy Kurs Visual Studio.

Quiz C#

Ostatnio przygotowałem również quiz C#, w którym możesz sprawdzić swoją wiedzę. Podejmiesz wyzwanie?

Wstrzykiwanie zależności z Lazy

Jednym ze sposobów rozwiązania powyższego problemu jest wstrzykiwanie zależności z Lazy, który jest wspierany przez większość kontenerów. Obiekty Lazy przechowują informacje o tym, jak utworzyć jakiś obiekt, i tworzą go dopiero podczas pierwszego użycia. Gdy chcemy ręcznie skorzystać z Lazy, wystarczy że przekażemy delegat tworzący obiekt do konstruktora. Natomiast w przypadku Autofac nie musimy nic specjalnego robić po stronie konfiguracji samego kontenera.

Aby skorzystać z Lazy, wystarczy tylko zmienić parametry w konstruktorze z IUserLogic na Lazy<IUserLogic>. Następnie korzystamy z właściwości Value obiektu Lazy, która udostępnia nam właściwy obiekt i tworzy go podczas pierwszego skorzystania z Value. W swoim kodzie nie korzystam bezpośrednio z obiektu Lazy, tylko opakowuje to prostą właściwością (co najlepiej widać na kodzie).

Poniżej znajduje się zmieniony kod, który korzysta z wstrzykiwania zależności z Lazy:

Jak widać, nie trzeba zbytnio zmieniać kodu, aby skorzystać z obiektów Lazy.

Na logu widać, że tworzone są tylko te obiekty, które są używane, oraz widać, że na przykład obiekt logiki jest tworzony już w trakcie wykonywania akcji. Pierwszy log pochodzi z wyświetlenia samego formularza (czyli tak samo, jak log wyżej), natomiast drugi log to próba zapisania formularza z błędem walidacji (nieustawione FirstName).

Podsumowanie

Wstrzykiwanie zależości z Lazy potrafi zwiększyć wydajność aplikacji poprzez nietworzenie obiektów, które nie są wykorzystywane. Dlatego właśnie warto korzystać z wstrzykiwania zależności z Lazy.

Zachęcam do zapoznania się z przykładem na githubie. Kod znajduje się w dwóch branchach:

  • master – wersja bez Lazy
  • Lazy – wersja z Lazy.

Kod zawiera też kilka różnych innych fajnych rzeczy, więc warto go pobrać i przejrzeć. 🙂

2 thoughts on “Wstrzykiwanie zależności z Lazy

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *