Castle Windsor – tryb życia komponentów
Wprowadzanie
W tym wpisie przybliżę sposoby definiowania trybu życia komponentów w kontenerze Windsor Castle.
Tryby życia
W aplikacji możemy skonfigurować w ramach jakiego zakresu dany komponent ma żyć oraz kiedy ma zakończyć swój żywot. Windsor dostarcza kilka takich trybów z pudełka, a należą do nich:
- Singleton - czyli jedna instancja na całą aplikację,
- Transient - jedna instancja na każde wywołanie z kontenera,
- PerWebRequest - instancja jest współdzielona w ramach jednego web requesta aplikacji webowej,
- PerThread - instancja komponentu jest współdzielona w ramach jednego wątku,
- Pooled - zostanie stworzona pula obiektów, z której na żądanie jest pobierana jedna instancja,
- Custom - można utworzyć własną definicję trybu życia instancji.
W 99 procentach korzysta się z pierwszych trzech, tj: Singleton, Transient oraz PerWebRequest. Pozostałych trybów życia instancji używa się sporadycznie.
Jeżeli nie zostanie wskazany tryb życia , to domyślnie Windsor Castle użyje trybu Singleton.
Przyjrzyjmy się zatem trybom życia z bliska, skupiając uwagę na trzech najczęściej używanych.
Singleton
Instancje pozyskiwane z kontenera o trybie życia Singleton są tworzone tylko raz w momencie gdy ktoś ich zażąda po raz pierwszy. Każde następne wywołanie powoduje uzyskanie tej samej instancji. Zniszczenie instancji o tybie życia Singleton nastąpi z chwilą zniszczenia instancji kontenera. Użycie metody container.Release() nie da żadnego rezultatu. Dobrym powodem na ustawienie instacji jako Singleton jest:
- bezstanowość danej instancji lub
- możliwość posiadania stanu, ale niezmiennego przez cały cykl życia aplikacji.
W przypadku Singletonu należy zwrócić uwagę na pracę z komponentem w środowisku wielowątkowym.
Konfiguracja Singletonu w instalatorze przedstawia poniższy przykład:
// domyślny Lifestyle to Singleton Register(Component.For<Car>()); // lub też explicite Register(Component.For<Car>().LifestyleSingleton());
Transient
Instancje o cyklu życia Transient są przeciwieństwem instancji o cyklu życia Singleton. Nie są przywiązane do żadnego kontekstu, a zatem każdorazowo kiedy prosimy kontener o komponent, otrzymujemy za każdym razem jego nową instancję. Dobrym powodem użycia Transient jest przypadek w którym chcemy kontrolować czas życia instancji przy użyciu container.Release(). Dodatkowo, jeżeli nie jest to koniecznie, nie musimy dbać o ich bezpieczeństwo w środowisku wielowątkowym.
Register(Component.For<Car>().LifestyleTransient());
PerWebRequest
W koncepcji działania jest hybrydą pomiędzy Singletonem a Transientem. Instancja zarejestrowana w takim trybie zostanie utworzona gdy zapytamy o nią kontener po raz pierwszy w trakcie trwania web requestu. Każde kolejne prośba utworzenia kończy się zwróceniem przez kontener tej samej instancji. Próba wykonania Relase() na instancji zakończy się fiaskiem
Register(Component.For<Car>().LifestylePerWebRequest());
Według opisu na stronie Castla, ustawienie takiego trybu życia instancji wymaga konfiguracji w aplikacji webowej odpowiedniego modułu tj. Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule
:
<httpModules> <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor"/> </httpModules>
Z kolei, jeżeli mamy do czynienia z IIS w wersji >= 7.0, wtedy musimy umieścić konfigurację w sekcji system.webServer/modules
:
<configuration> <system.webServer> <modules> <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" /> </modules> </system.webServer> </configuration>
Przykładowa aplikacja
Przykładowa aplikacja webowa napisana w ASP.NET MVC zostanie przedstawiona w kolejnym wpisie.
Leave a comment