Qi4j is very flexible in its usage and we don't force people to use any particular mechanism. Therefor Qi4j will not start itself, and has no configuration files, assembly descriptor files and so on. Getting Qi4j running is the responsible for the application, but it should not be mixed up with the domain model and business rules. Instead we expect that every application will have a bootstrapper, that starts everything and hand some artifacts over to the domain model part of the application, which will not have any view of the underlying infrastructure.The Runtime Bootstrap API is how such bootstrapper code in the application will get everything going.
For instance if you just want to create an Application with one Layer and one Module in that Layer, you would do something like this;
public static void main( String[] args ) throws Exception{ SingletonAssembler assembler = new SingletonAssembler() { public void assemble( ModuleAssembly module ) throws AssemblyException { // Add entities, services, objects, transients, values } };}
If the Application has a simple Layered architecture, i.e. no parallel Layers at the same level, but with many Modules in each Layer and many Assemblers in each Module, then another helper method can be used to create it fairly conveniently. Here is an example;
public static void main( String[] args ) throws Exception{ qi4j = new Energy4Java(); Assembler[][][] assemblers = new Assembler[][][] { { // View Layer { // Login Module new LoginAssembler(), : }, { // Main Workbench Module new MenuAssembler(), new PerspectivesAssembler(), new ViewsAssembler(), : }, { // Printing Module new ReportingAssembler(), new PdfAssembler(), : } }, { // Application Layer { // Accounting Module new BookkeepingAssembler(), new CashFlowAssembler(), new BalanceSheetAssembler( ), : }, { // Inventory Module new PricingAssembler(), new ProductAssembler(), : } }, { // Domain Layer // : }, { // Infrastructure Layer // : } }; ApplicationModelSPI model = newApplication( assemblers );
ApplicationSPI runtime = model.newInstance( qi4j.spi() );
runtime.activate();
}
private static ApplicationModelSPI newApplication(
final Assembler[][][] assemblers )
throws AssemblyException
{
return qi4j.newApplicationModel( new ApplicationAssembler()
{
public ApplicationAssembly assemble(
ApplicationAssemblyFactory factory )
throws AssemblyException
{
return factory.newApplicationAssembly( assemblers );
}
} );
}
For more complex and modularized applications one should use proper layering and modularization techniques. The principle is that Modules only exposes public Composites for other Modules to use, and that Layers can only reach Modules in the same Layer and Layers below.
ApplicationBuilderFactory sbf = api.getApplicationBuilderFactory();ApplicationBuilder builder = sbf.newApplicationBuilder();
{
LayerBuilder applicationLayer = ab.newLayerBuilder();
{
{
ModuleBuilder mb = applicationLayer.newModuleBuilder();
mb.addAssembly( new ApplicationAssembly() );
}
}
LayerBuilder viewLayer = ab.newLayerBuilder();
{
{
ModuleBuilder mb = viewLayer.newModuleBuilder();
mb.addAssembly( new ViewAssembly() );
}
viewLayer.uses( applicationLayer );
}
}
Application application = builder.newApplication();