TempHire is a reference application that has been designed from the ground up to scale to the needs of medium-to-large business applications. It demonstrates a range of architectural and design patterns, including repository patterns, Model-View-ViewModel (MVVM) presentation style, view composition, multi-screen navigation, data-binding, reusable UI components, validation, and multiple EntityManagers for sandbox editing, and cache management.
Being a reference app, we’ve kept TempHire manageable and limited its scope to something that highlights our enterprise design decisions without too many distractions. TempHire demonstrates a single Resource Management module in action, but you can see how additional modules (Scheduling, Customer Management, etc.) could easily be built on this framework.
Enterprise applications (line of business applications or LOBs) typically have task-oriented UIs and complex, cross-functional, workflows. They need multiple views and require considerable navigation. Given only a few screens, screen composition, decomposition, and data-binding to complex data models can get out of hand in a hurry.
Likewise, LOBs need to able to read, modify, and create data, so determining how to shuttle data back and forth between the UI and the back-end becomes yet another challenge. There’s a lot of tedious code involved in turning all that raw data into business objects and moving them to and from the client.
Putting all of the pieces together is enough of a challenge on traditional, relatively static, desktop clients; but more and more frequently, product requirements demand that these apps go cross-platform and work on desktops, tablets, and multiple mobile devices.
How do you design and write LOB apps that can handle real-world complexity? How do you build apps that can be easily maintained and extended over multiple years? How do you go cross-platform without hiring an army of developers to rewrite your code for multiple clients?
TempHire reduces complexity by leveraging frameworks like AngularJS for presentation and libraries like Breeze for data management, so developers can focus on solving business problems rather than the plumbing and wiring.
Even better, through the use of proven architecture and design patterns, multiple developers can work independently on specific views, models, and workflows without impacting other modules.
In this case we’re interested in the “tempHire” sample, located in the node/tempHire directory. These instructions assume this will be your current working directory.
At the top level you will find:
You can view, edit, and run the code in this project using the tools of your choice.
The sample assumes that you've installed node.js and MySql
Temphire uses projections and DTOs where applicable to improve performance and to move complex queries to the server. You can see this in action on the master details screen:
Frequently you’ll see grids like this populated by entities, but we don’t do that here. Instead, this grid uses a projection query that cherry picks the information from an object graph, condenses it, and sends it down the wire. Projections are a simple way to enhance performance, and your customers who are connecting via an EDGE network will be happy you did.
The client folder contains the core components of the TempHire client: AngularJS, Client Services, ViewModel code, the HTML Views, and main.js, the script that bundles the app’s scripts into a single package.
We’re assuming you’re familiar with the basics, so the most interesting components here are likely App/AngularJS and App/ Services.
AngularJS is a very popular front end SPA framework created by Google. For this sample, we are using a preliminary version of AngularJS 1.4 as well as it's new router. Please note that there may be issues that will be resolved once the router is final and we upgrade the sample to AngularJS 1.4 final release.
Entitymangerprovider.js offers a CreateManager method for TempHire to call whenever it needs a new EntityManager instance—something it does frequently as each UOW must spin up a new EntityManager. Logger.js takes care of TempHire’s logging functions, Repository.js is responsible for the configuration of UOW Repositories, and Unitofwork.js is responsible for the configuration of the UOW themselves.
All of TempHire’s content files (CSS and images) are stored in the client/css folder. This is a good time to mention that TempHire uses Twitter Bootstrap, an excellent template for quickly standing up a modern front-end.
HTML, CSS, UI elements, responsivity—yeah, Bootstrap takes care of all of that.
Bootstrap adds front-end pizazz with a variety of widgets, transitions, buttons, etc. It should go without saying that they all work seamlessly with the Twitter Bootstrap CSS (See Content). The various GUI elements are documented at twitter.github.io.
Breeze excels at data management and takes care of the Model –the M in MVVM. Breeze queries, saves, and manages all data interactions between client and server. Breeze EntityManagers make writing TempHire’s Unit of Work patterns considerably easier.
jQuery is a dependency for some of TempHire’s libraries and templates. Bootstrap, Breeze, and AngularJS rely on one bit of jQuery or another.
Toastr displays process and error notifications in "toast" windows that float up from the lower right to let you know what TempHire is doing at any given time.
All of TempHire’s persistence ignorance is built into the server-side services using Unit of Work (UOW) patterns.
The UOW is a design pattern that encapsulates anything from simple tasks to complex workflows. The UOW can be short or long lived, may involve retrieving data, modifying data, creating new data, performing business logic, checking business rules, and saving or rolling back changes.
An EntityManger is spun up for each UOW and takes care of the configuration, authentication, and connection details, while the UOW’s Repository handles the business logic that governs access to a specific type of entity.
UOWs make it possible to highly optimize the fetching strategy for a given entity type. e.g. A Repository for a static type such as Color can be optimized to load all colors on the first request and serve future requests directly from the cache instead of making additional trips to the server.
UOWs can be shared between ViewModels if different parts of the UI work with the same data, but each UOW remains a unique sandbox.
TempHire uses UOWs as transaction boundaries—each with customized responsibilities that lead to an organized codebase that’s easier to maintain and improve over time.
TempHire uses Node, Express, Sequelize and MySql with the help of our Breeze-Sequelize library.