Wstrzykiwanie zależności
Na podstawie obiektowego modelu konfiguracji, tworzona jest adekwatna struktura kontenerów IoC wraz z obiektami ComponentAdapter
, które odpowiedzialne są za instancjonowanie komponentów. Mechanizm zastosowany w platformie AgE dostarcza własną implementację klasy ComponentAdapter
, która przy rozstrzyganiu zależności wykorzystuje model konfiguracji (klasa CoreComponentAdapter
).
Podczas wczytywania modelu konfiguracji, dla każdej definicji komponentu, tworzony jest obiekt CoreComponentAdapter
, który umieszczany jest w kontenerze IoC. Adapter definiuje sposób instancjonowania komponentu, posiada referencję do definicji oraz wskazanie na wewnętrzny kontener IoC. Kontenery IoC tworzą hierarchię analogiczną do hierarchii definicji komponentów. Dzięki temu możliwe jest intuicyjne przesłanianie implementacji.
Na powyższym rysunku przedstawiony jest przebieg tworzenia komponentu wraz z inicjalizacją jego zależności. Kontener IoC otrzymuje od klienta żądanie uzyskania instancji komponentu (1), zawierające nazwę komponentu albo jego typ. Kontener wyszukuje po nazwie lub typie odpowiedni CoreComponentAdapter
i przekazuje mu żądanie dostarczenia instancji komponentu (2). Adapter przekazuje sterowanie do definicji komponentu (3), która ,,wie'' jak utworzyć instancję obiektu reprezentującego komponent. Ponieważ w przykładzie żądany komponent jest zależny od innego (DependencyA
), obiekt definicji pobiera ze swojego adaptera instancję zależności (4). Adapter natomiast przekazuje zapytanie do wewnętrznego kontenera IoC (5). Zapytanie to wygląda analogicznie do opisywanego przykładu (6-9). Po otrzymaniu referencji do żądanej zależności, obiekt definicji komponentu Component
, wstrzykuje ją do nowo tworzonej instancji komponentu (11). Proces wstrzykiwania zależy od wykorzystywanego mechanizmu (opisane wcześniej wstrzykiwanie przez konstruktor lub za pomocą adnotowanych pól lub metod). Tak utworzona instancja komponentu jest zwracana do klienta (12-14).
W przypadku inicjalizacji parametrów prostych, ich wartości są ustawiane za pomocą definicji komponentu podczas tworzenia obiektu reprezentującego komponent na postawie wartości przechowywanych w obiektowym modelu konfiguracji. Za parametry proste uważa się wszystkie wbudowane typy proste języka Java (int
, float
, boolean
, etc), napisy (String
) oraz adresy agentów (obiekty typu IAgentAddress
).
Dopuszczalna jest inicjalizacja komponentu w sposób mieszany, to znaczy za pomocą wstrzykiwania przez konstruktor i równocześnie wstrzykiwania za pomocą adnotowanych pól lub metod.
Opisywana infrastruktura pozwala na tworzenie reprezentacji komponentów, które są obiektami o zasięgu prototype i singleton. W pierwszym przypadku, w wyniku każdego żądania uzyskania komponentu skierowanego do kontenera IoC zostanie zwrócony nowy obiekt. Natomiast w przypadku singletonu, tylko pierwsze żądanie spowoduje utworzenie nowego obiektu, a następne żądania będą zwracać tylko referencję do już istniejącej instancji. Należy jednak pamiętać, że infrastruktura komponentowa nie zapewnia istnienia jednej instancji takiego obiektu w całym systemie, a tylko w obrębie jednej hierarchii kontenerów.
Wstrzykiwanie za pomocą adnotowanych pól lub metod umożliwia automatyczne dobieranie zależności po typach, bez konieczności definiowania ich w obiektowym modelu konfiguracji (mechanizm auto-wiring). Wszystkie właściwości obiektu mogą zostać automatycznie zainicjalizowane na podstawie ich typu pod warunkiem, że w kontenerze IoC istnieje dokładnie jedna implementacja żądanego typu.