Subcontexts

Definition

Subcontexts allow to modularize an application and to define reusable components of services and configurations. Instead of using a single context class it is possible to build a hierarchy of context classes that form a tree. The context at the root is called the main context. Each context can define it's own set of services and configurations. The upper contexts can reference their subcontexts directly.

A subcontext is defined by annotating a method with the @Subcontext annotation. The return type of the method must match the concrete type of the subcontext class. Annocon ensures that the subcontexts are singletons:

@Context(id="main") 
public class MainContext
{
  @Subcontext()
  public Subcontext1 getSubcontext1()
  {
    return new Subcontext1();
  }

  @Subcontext()
  public Subcontext2 getSubcontext2()
  {
    return new Subcontext2();
  }

  @Service(id = "Service1")
  public SimpleService getService1()
  {
    return new SimpleService(getSubcontext1().getService1());
  }
}
  
@Context(id = "subcontext1")
public class Subcontext1
{
  @Service(id = "Service1")
  public SimpleService getService1()
  {
    return new SimpleService();
  }
}

During the wiring of Service1 in the main context the services defined in the subcontext can be accessed strongly typed. The autowiring functionality is aware of the services in the subcontext too.

Namespaces

Each context inside a hierarchy must have a unique id. The id is used to form namespaces in which the elements (services, configurations etc.) of a context exist. The id is comparable to a java package identifier. An element is fully qualified by the id of the context that defines it and the id declared in the corresponding annotation. For example the fully qualified id of service1 in the main context is main.service1. Whereas the service1 in the subcontext1 is qualified by subcontext1.service1.

These namespaces are required to allow contributions to configurations defined in different contexts (distributed configurations). Another use case is the reflective access to services and configurations.

Distributed configurations

The described contributions mechanism allows to contribute to configurations defined in another subcontext or the main context. The attribute configurationId must then contain a fully qualified id:

@Context
public class Plugin1
{
  @Contribution(configurationId = "swing.application.Menu")
  public void contributeMenuItems(JMenuBar menuBar)
  {
    ...
    JMenu menu = new JMenu("Edit");
    menuBar.add(menu);
    ...
  }
}
@Context(id = "swing.application")
public class SwingContext
{
  @Configuration(id = "Menu")
  public JMenuBar getMenuBar()
  {
    JMenuBar menuBar = new JMenuBar();
    ...
    return menuBar;
  }
}