Angular2 Constructor Guards…

Right from the angular docs

You can use this method to prevent accidental loading of a previously loaded module..

How can I tell if a module or service was previously loaded?

Some modules and its services should only be loaded once by the root AppModule. Importing the module a second time by lazy loading a module could produce errant behavior that may be difficult to detect and diagnose.

We can guard against that danger by writing a constructor that attempts to inject the module or service from the root app injector. If the injection succeeds, the class has been loaded a second time. We can throw an error or take other remedial action.

Certain Angular modules (such as BrowserModule) implements such a guard as does this Angular Module chapter sample’s CoreModule constructor.

app/core/core.module.ts
constructor (@Optional() @SkipSelf() parentModule: CoreModule) {
 if (parentModule) {
 throw new Error(
 'CoreModule is already loaded. Import it in the AppModule only');
 }
}

Angular 2 notes

First credit to Deborah Kurata for her excellent course @ plural sight.

All my code is located here: github repo which is a cloned version from Deborah’s course code…  It is great for trying out new concepts!

Angular Modules

Every angular application has at least one module class which is the root module.   Of course that module is bootstrapped (in main.ts)  in order to run (launch) the application.

  1. They must be decorated with @NgModule  a metadata class decorator.
  2. Should be exported (public) so other component templates can use them
  3. Often import other modules
  4. Could provide services to any application component
  5. Aid in organization of application, often referred to as feature modules.  These are then imported into the root module

Quick Start Angular Application folder structure

QuickStart Angular folder structure inside the app folder

The application root module – AppModule

This module is used to tell Angular how the application is pieced together.  As noted earlier, all Angular applications must has at least one Angular Module.

Following conventions, its name is AppModule.  For step a step by step guide on how to create this manually, see this link.

Here is a most basic example as created from the QUICK-START app.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';

@NgModule({
 imports: [ BrowserModule ],
 declarations: [ AppComponent ],
 bootstrap: [ AppComponent ]
})
export class AppModule { }

Here you will notice the Import statements which pull in resources the application will need.  Since I work with browser based applications my app.module.ts will almost always use the BrowserModule (more notes on it below).

NgModue observations

  1. This sets up the metadata used in the module.
  2. All metadata items are functions.
  3. NgModule is an interface with many options like: providers, declarations, imports, export and etc…
  4. For details on the module and the metadata options see this link.

BrowserModule

  1. Provides services for launching and running your application in a browser
  2. Re-Exports the CommonModule which provides access to Angular Directives (NgIf, NgFor…)

The BrowserModule provides services that are vitally important to run your application in a modern browser like chrome of I.E. Edge.

Note:  Do not import BrowserModule in any other module. Also you cannot lazy load this module.

After wiring up what is required we will will want to begin importing our actual application components.  For example, we import a component known as app.component.ts as generated in the quick-start files.

import { Component } from '@angular/core';

@Component({
 selector: 'my-app',
 template: '

{{title}}

‘, }) export class AppComponent { title = ‘Minimal NgModule’; }

This simply shows a title using a form of data binding known as string interpolation .  The value for the title comes from the exported class property title.

@NgModule

  1. You should notice in the app.module.ts the declarations and bootstrap metadata properties for NgModule have AppComponent in them.
  2. The declarations property list identifies the application’s only component, the root component.
  3. The bootstrap property is used to identify the AppComponent as the bootstrap component.  It is what kicks things off.

When an Angular application kicks off, it puts the HTML rendering of AppComponent in the DOM. In the quick start it is as defined in its @Component metadata selector.  For more info on the @Component decorator see this link.

The magic of Bootstrapping

So where does the actual bootstrapping occur?  Well, in most cases the index.html file will call the system.js.config.js file which in turn calls the main.ts (js) file when then kicks off the actual bootstrapping process.  If you are using a Angular Quickstart or CLI tool you will not need to worry about this for the vast majority of applications you will write in Angular.

Maybe an illustration will aid:

Angular Bootstrap process

Angular Bootstrap process

The above example is how the dynamic bootstrapping occurs. Which basically means the browser is shipped the Angular compiler  which then compiles our application in the browser.  For development or small applications this is fine.  But for performance you want to use the static bootstrapping method known as Ahead-Of-Time (AOT) Compilation.  Read more here about AOT.

Basic steps to adding a Component

First decide is this a stand alone component or will it be a nested component?

A stand alone will not have a selector property in the @Component metadata which a nested will need the selector defined.

I like to begin with an empty shell of a html file which will be our template.  I greatly prefer a html template over a inline template.

Naming convention for the file.

This will vary but I like to place my files in a folder that relates the purpose.  For example I am going to create a component that will list out a set of products.

So I create a folder called Products under the app folder.

Then I add a file called product-list.component.html

Then I add a product-list.component.ts file

In the product-list.component.ts file I will need a few basic things to kick the process off…

  1. create the class and besure to export it.
  2. Add the @Component decorator and them import it @angular/core
  3. Add the metadata needed.  Since the list is a root component it will not be nested, no selector is needed. But I will need a templateUrl and the moduleId decorator.
  4. Add an import for your data service if needed and include any services in the constructor.
  5. If you are going to respond to events you will need to include them from the core library.

Here is an example:

import { Component, OnInit } from '@angular/core';


import { IProduct } from './product';
import { ProductService } from './product.service';

@Component({
 // selector: 'pm-products', we are no longer nesting 
 moduleId: module.id,
 templateUrl: 'product-list.component.html',
 styleUrls: ['product-list.component.css']
})
export class ProductListComponent
 implements OnInit {
 //Image Properties
 imageWidth: number = 25;
 imageMargin: number = 2;
 showImage: boolean = false;

 pageTitle: string = 'Product Listing';
 listFilter: string;

 products: IProduct[];

 errorMessage: string;

 /** 
 * Long Contructor Method
 * private _productService: ProductService;
 *
 * constructor(productService: ProductService) {
 * this._productService = productService;
 * }
 */

 constructor(private _productService: ProductService) { }
 ngOnInit(): void {
 console.log('In OnInit');
 console.log('Module ID: ' + module.id);
 //this.products = this._productService.getProducts();
 this._productService.getProducts()
 .subscribe(products => this.products = products,
 error => this.errorMessage = error);
 }

 // Methods
 toggleImage(): void {
 this.showImage = !this.showImage;
 }
 onRatingClicked(message: string): void {
 this.pageTitle = 'Product List: ' + message;
 }
}

The Html Template

{{pageTitle}}
Filter by:

Filtered by: {{listFilter}}

ProductCodeAvailablePrice5 Star Rating
{{product.productName}}{{product.productCode}}{{product.releaseDate}}{{product.price | currency:’USD’:true:’1.2-2′}}

{{showImage ? ‘Hide’ : ‘Show’}} Image

Of course as your application grows you should use the angular module system to aid in organizing your code and help with lazy loading…

The product module code:

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';

import { SharedModule } from '../shared/shared.module';
import { ProductService } from './product.service';
import { ProductListComponent } from './product-list.component';
import { ProductFilterPipe } from './product-filter.pipe';
import { ProductDetailComponent } from './product-detail.component';
import { ProductDetailGuard } from './product-guard-service';

import { ProductRoutingModule } from './product-routing.module';

@NgModule({
 declarations: [
 ProductListComponent,
 ProductDetailComponent,
 ProductFilterPipe
 ],
 imports: [
 SharedModule,
 ProductRoutingModule
 ],
 providers: [
 ProductService,
 ProductDetailGuard]
})
export class ProductModule {

}

This all of course must be wired up in the app.module.ts code in the app root folder…

Here is an example:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
//import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { RouterModule } from '@angular/router';

import {AppRoutingModule} from './app-routing.module';
import { AppComponent } from './app.component';
import { WelcomeComponent } from './home/welcome.component';
import { ProductModule } from './products/product.module';

@NgModule({
 imports: [BrowserModule,
 HttpModule,
 ProductModule,
 AppRoutingModule], // If you want to use # in your routes, set the following .forRoot([], {useHash: true}) - I think this is default for IIS7
 // directives, components and pipes by Angular, External or third party 
 declarations: [AppComponent, WelcomeComponent], // Our directives, components and pipes
 bootstrap: [AppComponent]
})
export class AppModule { }

StructureMap, IoC -MVC Controller parameterless constructors

Example VS 2015 Solution [ link ] for this article

StructureMap (SM) is one of the most popular IoC tools for MVC out there.  But, one of the biggest issues for first timers is the web has tons of post on it and often they are not clear on the version and etc…

For this Article I am using:

  • .Net 4.5.2
  • MVC 5
  • StructureMap  3.1.1.134
  • StructureMap MVC5

Official documentation:  http://structuremap.github.io/

As you may already know, the MVC default controller factory defaults to parameterless constructors.  When you change a Controller it accept a parameter, the .net mvc compiler will complain about it.  Often you will see an error that reads: No parameterless constructor define for this object. To solve this issue you will need to implement your own ControllerFactory and get it to pass request for controllers through structuremap (SM) or you can use the SM MVC 5 Nuget package in Visual Studio (later in this article). SM, will then inspect each request and attempt to resolve those dependencies with a concrete implementation.

A mvc controller class with a parameter based constructor as the default.

public class ContactController : Controller
{
  private readonly IContactRepository iRepository;

  public ContactController(IContactRepository repository)
  {
    iRepository = repository;
  }

  public ActionResult Index()
  {
    return View(iRepository.GetContacts());
  }
}

In the above code you will see I have a constructor that is expecting some kind of repository for contacts.  So as I was saying above, you will need to create a Default Controller Factory.   This grunt work can be avoided if you use any of the nuget packages for MVC and Structure Map.  But for if you want to do it manually you will need to wire things up yourself.

A bit more succinctly, since MVC framework has its own default implementation of the IControllerFactory interface which is DefalutControllerFactory and since it is not a sealed class so you can extend it.  So you override the virtual method GetControllerInstance and change the implementation to whatever we need and then register this in the global.asax.cs file start up.  (I suggest you not do this…)

Instead, you can make this much easier by leveraging a nuget package to do most of the grunt work for you.

An example of implementing the DefaultControllerFactory:

using System;
using System.Web.Mvc;
using StructureMap;

namespace ContactManager.IoC
{
  public class DependencyControllerFactory : DefaultControllerFactory
  {
    protected override IController GetControllerInstance(Type controllerType)
    {
        return ObjectFactory.GetInstance(controllerType) as Controller;
    }
  }
}

 

Leveraging your IDE’s tools…

In visual studio 2015 I created a simple mvc application. See this [ link ] for the code accompanying this blog post…

Then I went into Nuget and added StructureMap MVC5. ( https://www.nuget.org/packages/StructureMap.MVC5/ )

 

What caught me off guard initially was that I did not see any code in the application_start method referencing the StructureMap Dependency resolver or such.  After digging about I figured out it was using an assembly trick to wire up SM before the application start.  See this link for a quick explanation of PreApplicationStartMethod.

In App_Start folder you will see a file called StructuremapMvc.cs.  Open it and look for these two entries..

[assembly: PreApplicationStartMethod(typeof(StructuremapMvc), “Start”)]
[assembly: ApplicationShutdownMethod(typeof(StructuremapMvc), “End”)]

This is what wires up your mappings of concrete implementations of interfaces located in the DefaultRegistry.cs file in the DependencyResolution folder in your solution.

So all you have to do now is update the DefaultRegistry.cs file with you specific needs using the For<>.Use<>(); syntax.

Code-ON…

A few misc reads and link:

Look here for more details on the mvc 5 nuget package for MVC  https://github.com/webadvanced/Structuremap.MVC5

For specific integratinos: http://structuremap.github.io/integrations/

General Nuget package:  https://www.nuget.org/packages/structuremap/

Structuremap and entity framework can be a bitch, read this:

Entity Framework – The best example is this blog post from Jimmy Bogard.

So some quick unstructured notes…

Caramelized Garlic Tart

Click for a Digital Printer Friendly Recipe 
tart.jpg  Tender sauteed garlic cloves make a flavorful filling for this quiche-like tart.

Ingredients

13 ounces puff pastry, defrosted if frozen

3 medium heads of garlic, cloves separated and peeled

1 tablespoon olive oil

1 teaspoon balsamic vinegar

3/4 tablespoon sugar

1 teaspoon chopped fresh rosemary

1 teaspoon chopped fresh thyme, plus 3 sprigs for garnish

3/4 teaspoon fine sea salt

4 1/2 ounces soft, creamy goat cheese, such as chevre

4 1/2 ounces hard, mature goat cheese, such as goat gouda

2 large eggs

6 1/2 tablespoons heavy cream

6 1/2 tablespoons creme fraiche

Freshly ground black pepper

Directions

  1. Roll out puff pastry into a 16-inch circle. Fit puff pastry into an 11-by-1 1/2-inch round fluted pan with a removable bottom. Place a parchment paper-round on top of puff pastry; top with pie weights or dried beans. Transfer to refrigerator; chill for 20 minutes.
  2. Preheat oven to 350 degrees. Transfer tart shell to oven and bake for 20 minutes. Remove weights and paper and bake until pastry is golden, 5 to 10 minutes more. Remove from oven and set aside.
  3. Place garlic cloves in a small saucepan filled with water. Place saucepan over medium heat and bring to a simmer; simmer for 3 minutes. Drain and return cloves to saucepan. Add olive oil and place saucepan over high heat; cook, stirring occasionally, until garlic is fried, about 2 minutes. Add vinegar and 1 cup water; bring to a boil and immediately reduce to a simmer. Let simmer for 10 minutes. Add sugar, rosemary, chopped thyme, and 1/4 teaspoon salt. Continue simmering over medium heat until most of the liquid has evaporated and garlic is coated in a dark caramelized syrup, about 10 minutes more. Remove from heat and set aside.
  4. Break both goat cheeses into pieces and scatter in tart shell; spoon garlic cloves and syrup over cheese. In a large glass measuring cup, whisk together eggs, cream, creme fraiche, and remaining 1/2 teaspoon salt; season with pepper. Pour egg mixture over cheese and garlic filling, making sure the cheese and garlic are still visible.
  5. Transfer tart to oven and bake until tart filling is set and top is golden brown, 35 to 45 minutes. Remove from oven and let cool slightly before removing tart from pan. Trim tart as necessary and garnish with thyme sprigs; serve.

Recipe Measurement Guides

Simple Unit of Measurements (Source wiki)

List of Units

Volume
teaspoon (also t or tsp.)
tablespoon (also T, tbl., tbs., or tbsp.)
fluid ounce (also fl oz)
gill (about 1/2 cup)
cup (also c)
pint (also p, pt, or fl pt – Specify Imperial or US)
quart (also q, qt, or fl qt – Specify Imperial or US)
gallon (also g or gal – Specify Imperial or US)
ml, also milliliter, millilitre, cc (and mL only in the US, Canada and Australia).
l, also liter, litre, (and L only in the US, Canada and Australia).
dl, also deciliter, decilitre (and dL only in the US, Canada and Australia).
Mass and Weight[edit]
pound (also lb or #)
ounce (also oz)
mg (also milligram or milligramme)
g (also gram or gramme)
kg (also kilogram or kilogramme)

You know a recipe is a professional level grade recipe when they use weights and not cups or such…

A scale that allows you to tare (zero out) is critical for this.

So if a recipe called for 1 lbs of something you would place your container on it, press the tare button and the scale zero’s out the weight of your container.  Then you add your ingredient.  Then for the next ingredient, you tare the scale again and repeat as needed.  Works great and very fast…

A scale with tare functionality:

tare-scale

Liquid Measuring

If the ingrediant is wet you want to measure using devices that are for that.  I can’t tell you how many times I seen someone use a measuring instrument for dry stuff and wonder why they got a differetnt result than the recipe…

For wet use a measuring cup like these:

liquid

Dry Measuring

Dry measuring cups are usually made of metal or plastic and have an even rim. You dip the cup into the dry ingredients and level off with the straight edge of a knife.

So if it is a dry ingrediant use a cup or similar measuring device.

For example:

drymeasure

CHAI TEA MIX

CHAI TEA MIX

1 cup nonfat dry milk powder
1 cup powdered non-dairy creamer
1 cup vanilla-flavored powdered non-dairy creamer
2 1/2 cups white sugar
1 1/2 cups unsweetened instant tea
2 t. ground ginger
2 t. ground cinnamon
1 t. ground cloves
1 t. ground cardamom
chaitea

Mix all ingredients together. In a blender or food processor, blend one cup at a time, until mixture is consistency of fine powder.

TO SERVE: Stir 2 heaping tablespoons Chai Tea mixture into a mug of hot water.

Do I use a dry or wet measurement device? Answer: Measurement guide

Fake Maple Syrup…

So I am on a quest to make a maple syrup flavored oatmeal cookie.

Now my first experiments will be with extracts and my final will be with the real stuff.

The “Fake” Maple Syrup

The Recipe (1):

  • You’ll need to bring 1 cup of water to a boil
  • Then add 1 cup of white sugar
  • 1 cup of brown sugar
  • ½ teaspoon of Mapeleine.   Other Maple Extracts @ Amazon

Keep stirring until the sugar is dissolved and remove the pot from the heat and let it cool down. When it reaches room temperature, pour it in a syrup dispenser or mason jar and keep in the fridge for up to three months.

Now why would I use an extract versus the real thing… simple – to keep the sugar down and cost down.  But for my cookie recipe I would be adding this in directly instead of making a syrup.

Next up, I will be using a syrup.. but first I have to research what make a good maple syrup and more importantly, what makes it task strongly of “maple”…

Sources:

  1. Lifehacker Recipe
    DIY Maple-Flavored Pancake Syrup