blob: 5de3187a4e507af7b7a182285b8ca3d556d14ee3 [file] [log] [blame]
///////////////////////////////////////////////////////////////
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
///////////////////////////////////////////////////////////////
[[core-api-dependency-injection,Dependency Injection]]
= Dependency Injection =
Polygene has a rather sophisticated dependency injection system, which is based around the <<core-api-modules>>
and <<core-api-visibility>> concepts. The dependency injection system also need help to keep the injection scopes
separated. The following injection scopes exists, some more common than others;
* ++@This++ - injection of fragment from the same Composite instance.
* ++@Structure++ - injection of <<core-api-structure>> organized types.
* ++@Service++ - injection of services.
* ++@Uses++ - injection of construction injected objects
* ++@Invocation++ - injection of parts related to the current method invocation.
* ++@State++ - injection of state of the composite instance
* Custom injection scopes - managed through ++@AppliesTo++ and ++AppliesToFilter++ declarations.
[[core-api-this,@This]]
== @This ==
++@This++ is equivalent to the ++this++ pointer in the Java language, but refers to any part of the current
<<core-api-composite>>. This can either be a declared mixin type, or if not declared will be a <<def-private-mixin>>.
=== Example ===
We can simply request the injection of any type of the composite that we belong to, such as;
[source,java]
--------------
@Mixins( { OrderMixin.class, ShippingMixin.class } )
public interface Order extends HasShippingInformation
{
:
}
public abstract class OrderMixin
implements Order
{
@This
private HasShippingInformation shipping;
}
--------------
But we can have <<def-private-mixin>> instead, where the injected mixin type will be automatically added to the
composite.
[source,java]
--------------
@MIxins( OrderMixin.class )
public interface Order
{
:
}
public class OrderMixin
implements Order
{
@This
private DiscountRate discount;
--------------
[[core-api-structure-injection,@Structure]]
== @Structure ==
The ++@Structure++ injection scope is all about the types involved in the Application <<core-api-structure>> system.
The possible types are;
* Application
* ApplicationDescriptor
* Layer
* LayerDescriptor
* Module
* ModuleDescriptor
* ModuleSPI
* UnitOfWorkFactory
* EntityBuilderFactory
* ValueBuilderFactory
* TransientBuilderFactory
* ObjectFactory
* QueryBuilderFactory
* ServiceFinder
* PolygeneAPI
* PolygeneSPI
[[core-api-service,@Service]]
== @Service ==
Services are injected either in a number of ways, either direct, via List or via ServiceReference types. The following
combinations are allowed;
[source,java]
--------------
@Service
private MyService service;
@Service
private Iterable<MyService> services;
@Service
private ServiceReference<MyService> service;
@Service
private Iterable<ServiceReference<MyService>> services;
--------------
If service is not declared ++instantiateOnStartup++ during assembly, then the service will be activated on first
method invocation, and not on injection. This means that any reflection on the injected instance, may result in
unexpected behavior.
[[core-api-uses,@Uses]]
== @Uses ==
<<def-object>> and <<def-valuecomposite>> can be created with ++uses()++ declarations. This allows injection of
arbitrary types to these meta types. Only type matching will occur, so for instance only one String can be injected
this way.
If a ++@Uses++ declaration can not be satisfied from the injected objects via ++uses()++ builder method, then
if the ++@Uses++ injection is not ++@Optional++ the Polygene runtime will attempt to (in this order)
* Instantiate a visible <<def-transientcomposite>>
* Instantiate a visible <<def-object>>
* Instantiate a plain object with this Composite instance as a single constructor argument.
If the ++@Uses++ is ++@Optional++ then no implict object creation will take place.
[[core-api-invocation,@Invocation]]
== @Invocation ==
++@Invocation++ injection scope is all about the current method call. It is possible to inject the following types;
* The ++Method++ being executed.
* Any annotation type that the method is annotated with.
* An ++Iterable++ of either of the above
[[core-api-state,@State]]
== @State ==
This injection scope can inject either state related types.
* ++StateDescriptor++ which holds metainfo about the state of the Composite,
* ++StateHolder++ which allows inspection of current state of the Composite,
* <<def-property>> to get a direct reference to a declared ++Property++
* <<def-assocation>> to get a direct reference to a declared ++Association++
* <<def-manyassociation>> to get a direct reference to a declared ++ManyAssociation++
* <<def-namedassociation>> to get a direct reference to a declared ++NamedAssociation++
[[core-api-custom-injection,Custom Injection Scopes]]
== Custom Injection Scopes ==
Custom Injection scopes are not yet supported.