The choices made when setting out to build an application can either contribute to the success or failure of a project. Execution environment/platform, source control management, testing strategies, tools, languages, code organization, and software architecture are all key decisions at the beginning and throughout the development of a project. New frameworks like Angular 2 have little guidance or reference material to help you move down a successful path when setting out to build what would be considered a non-trivial application.
Currently, I am focused on acquiring an in-depth knowledge of Angular 2. Having worked with Angular 1.x for the past couple of years, I am excited about the value that Angular 2 delivers. I learn by doing, so I have set out to build a simple web application (Speaker Register) that allows conference speakers to create searchable profiles that are available to conference and meeting planners. I have decided to use a SPA (Single-Page Application) architecture using Angular 2 and ASP.NET Web API hosted on ASP.NET 1.0 Core and .Net Core 1.0. The application’s repo is located here: https://github.com/rightincode/speakerregister Feel free to follow along as the application evolves over the next several weeks.
Below is a high-level diagram of the current software architecture of the Angular 2 code:
Angular 2 applications are intended to be modular by organizing your code into modules. Modules are blocks of code dedicated to a single purpose and inherently support re-use. They consolidate components, directives, and pipes (angular concepts) into cohesive blocks of functionality focused on a feature area, workflow, or common collection of utilities (library). Modules export something of value, for example, a class, function, value, service, and/or component. The exported items can be imported by other modules.
An Angular 2 application contains at least one module that is named the root module. Angular 2 launches an application by bootstrapping the root module. Additional modules, named feature modules or shared modules can be used to separate concerns and better organize an application. An Angular 2 module is a class (a Typescript class in the case of the sample application) that is decorated with the @NgModule decorator function. Let’s take a look at the modules in Speaker Register.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HTTP_PROVIDERS } from '@angular/http';
/* App Root */
import { AppComponent } from './app.component';
import { PageNotFoundComponent } from './pagenotfound.component';
import './rxjs-operators';
/* Feature Modules */
import { SpeakerModule } from './speaker/speaker.module';
import { ConferenceModule } from './conference/conference.module';
/* Routing */
import { routing, appRouterProviders } from './app.routing';
@NgModule({
imports: [BrowserModule, ConferenceModule, SpeakerModule, routing],
declarations: [AppComponent, PageNotFoundComponent],
providers: [appRouterProviders, HTTP_PROVIDERS],
bootstrap: [AppComponent]
})
export class AppModule { }
The AppModule is the root module of the Speaker Register application. Lines 17-22 above is where Angular is instructed that the exported class AppModule is a module. The @NgModule decorator function accepts an object that contains metadata (configuration information) that describes features of the module.
- imports: (line 18) this is a list of modules who exposed assets (directives, pipes, etc.) are available to templates in this module. In the code above, BrowserModule is imported from the Angular library. ConferenceModule and SpeakerModule are two other modules (feature modules) that contain specific functionality for those areas of the Speaker Register application. (routing is beyond the scope of this post but will be covered later)
- declarations: (line 19) this is a list of the components, directives, pipes, etc. that belong to this module. AppComponent (container component for the application) and PageNotFoundComponent belong to the root module
- providers: (line 20) this is a list of injectable objects that are available in the injector of this module. (providers are beyond the scope of this post but will be covered later)
- bootstrap: (line 21) the list of components that should be bootstrapped when this module is bootstrapped. In the code above, AppModule is our root module and when it is bootstrapped, AppComponent (the container component for the application) is bootstrapped
When the application starts, AppModule gets bootstrapped. (starts executing) AppModule imports several modules from the Angular libraries, imports two components (AppComponent and PageNotFoundComponent – we will cover those in a later post) that are a part of AppModule, loads two feature modules (SpeakerModule and ConferenceModule), and sets up routing. (we will cover routing in a later post)
Speaker Register also has two feature modules named SpeakerModule and ConferenceModule. Both of these modules export classes that are decorated by the @NgModule function similar to the AppModule. They contain only what is needed to implement the features of those parts of the application. This allows for the separation of concerns between modules in the application. For example, the SpeakerModule is only concerned about the speaker functionality and exports an API to modules that import it. It (SpeakerModule) can be updated independently without a negative impact to other modules as long as the API has not changed after the updates. Take a look at the SpeakerModule and ConferenceModule in the source code: https://github.com/rightincode/speakerregister
The module in Angular 2 is a very powerful tool to help organize your code and build a codebase that is much easier to maintain. In Speaker Register, we have made use of the module to create a software architecture designed to separate the concerns of specific areas within the application. Add this tool (module) to your toolbox. It will help you create a successful software architecture for your Angular 2 applications.
Keep Right’in Code!
Richard – @rightincode