Click here to Skip to main content
15,069,297 members
Articles / Web Development / XHTML
Posted 23 Oct 2016


34 bookmarked

Angular2 & WebApi(SPA) for Enterprise App - Part 3 - Project Structure

Rate me:
Please Sign up or sign in to vote.
3.73/5 (13 votes)
4 Jul 2017CPOL3 min read
This tip explains how we should structure our project folder

Other Articles in the Series

  1. Overview
  2. Add new Permission
  3. Project structure
  4. Multi-Languages (i18n)
  5. DI & IoC - Why and Why not?
  6. RESTful & WebApi
  7. Manage Application Lifecycle
  8. Build & Deploy Application
  9. New version of TinyERP with Angular 2 (typescript)
  10. CQRS: Avoiding performance issues in enterprise app (basic)
  11. Multiple data-stores: Scale your repository (Part 1)
  12. Multiple data-stores: Scale your repository (Part 2)
  13. Basic authentication (user name/ password) with OWIN
  14. Token based authorization with OWIN


In this tip, we learn how to organize the project for our application.

I assume that our application has the following features as shown in the image below:

Image 1

In this image, we see that:

  • The application has 3 big features: Security, HRM, CRM. We usually call them as module. So in the sample application, we have 3 modules: Security module, HRM module and CRM module
  • Each module should be isolated from others. I mean, in Security module will not manage staff, ...
  • From 1 module, should not depend on others as they are isolated each others.
  • We should use event for module communication, I mean, Security module wants to call some action in HRM module. Security should fire an event, HRM will subscribe to that event with appropriate event handler. This will help us reduce the complexity of the application, and is easier for maintenance in the future.
  • Each big feature has it own sub features, such as in Security, we have Permission, User Role, User, ...
  • Each sub feature (such as Permission) can be implemented in one or more pages (such as list of permissions, create permission, update permission, ...)

Project Structure

With the above application, we will organize the structure as below:

Image 2

From the image above:

  • Each module will have its own route, menu items, .... this information was specified in "<root>/app/modules/<name of module>/_share/config/module.ts"
  • Each module and its sub features will be located in it own folder in <root>/app/modules/<name-of-module>.
  • Sub feature of module has its own folder (such as permission for permission sub feature) and contains its detailed implementation (list of permissions, add permission, update permission). This will make it easier for us to locate and modify the code.
  • Service class, used by appropriated sub feature (such as permissionService) should be located in "_share/services" folder in appropriated module. permissionService was not only used inside permission sub feature but also in other sub features in the same module (such as usergroup, user).
  • For directives, used by any sub-features on module. they should be located in "_shared/directives" folder. For example, "permissions" directive (showing the list of permissions) can be users in permission, user sub-feature.

If this directive was located inside "<root>/app/security/permission". In user sub-feature, we need to duplicate or import from permission sub-feature (this will create dependency between user and permission sub-feature). It is not good.

If this directive was located inside "<root>/app/common/directives". The number of directives in this folder will be immense and most of them were used in 1 module only.

  • Inside 1 module, we will fire event if we want to notify other modules.
let eventManager = window.ioc.resolve("IEventManager");
eventManager.publish("<event-key>", <event argument>);
  • Multi languages (i18n) resource was located in "<root>/app/resources/locales/<name of module>.<language>.json" (such as: security.en.json or

Each module should have only 1 file for 1 language.

All sub-features of module should use texts inside this json file following the convention "<name of module>.<name of sub-feature>.<name of implementation>.<name of text>". For example, "security.permission.permissions.pageTitle" will return the text used for title of permission page in permission sub-feature of security module.

The same rules were applied for HRM, CRM modules.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author
Vietnam Vietnam
I have more than 8 years in web development for multiple types of applications (ERP, Education System, ...).
I usually organize training/ coaching on specified topic (such as: RESTful/ WebApi, Angular2, BEM, LESS, SASS, EF, NodeJs ....). Please contact me on Skype (tranthanhtu83) or email ( if need.
For more information about me, Please visit

Comments and Discussions

General$.fn.popover is undefined in TinyERP Pin
Mohidul Islam8-Jul-17 9:28
MemberMohidul Islam8-Jul-17 9:28 
AnswerRe: $.fn.popover is undefined in TinyERP Pin
tranthanhtu.vn10-Jul-17 3:17
professionaltranthanhtu.vn10-Jul-17 3:17 
QuestionDynamic loading modules Pin
Blagojce-MKD18-Nov-16 22:06
MemberBlagojce-MKD18-Nov-16 22:06 
AnswerRe: Dynamic loading modules Pin
tranthanhtu.vn19-Nov-16 2:30
professionaltranthanhtu.vn19-Nov-16 2:30 
PraiseNice Series Pin
prgmr61-Nov-16 14:54
Memberprgmr61-Nov-16 14:54 
GeneralRe: Nice Series Pin
tranthanhtu.vn1-Nov-16 17:01
professionaltranthanhtu.vn1-Nov-16 17:01 
QuestionMissing image: Pin
Member 963653525-Oct-16 15:06
MemberMember 963653525-Oct-16 15:06 
AnswerRe: Missing image: Pin
tranthanhtu.vn26-Oct-16 3:14
professionaltranthanhtu.vn26-Oct-16 3:14 
PraiseGreat Pin
JamesDaniels197023-Oct-16 9:36
MemberJamesDaniels197023-Oct-16 9:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.