erotik film
bodyheat full moves www xxx kajal video la figa che sborra ver video de sexo porno
Luxury replica watches
sex
film izle film izle casino siteleri tipobet giris
asyabahis
escort antalya

When you buy this book you support this site! - Thank You for your support!

Nov 18

Written by: Michael Washington
11/18/2017 6:14 PM  RssIcon

Using the open source Typewriter plug-in with Visual Studio will allow you to automate much of the boilerplate code for your classes and services.

image

A modern .Net Core 2.0 Angular 4+ application is usually composed, on the Angular client-side, of Components, Services and Classes (written in TypeScript), and Controllers and Classes on the server-side.

image

Using Typewriter, the Angular classes and services will be auto-created. This will be accomplished by creating a template (a .tst file) that will read the server-side code and auto-create the corresponding Angular code.

 

Install and Use Typewriter

image

You can download and Install Typewriter at the following link.

It will install as a plug-in in Visual Studio.

Creating Classes

image

In Visual Studio, we will create an Angular project and then create a class using the following code:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace TypeWriterTest.Models
{
    public class CarDTO
    {
        public int id { get; set; }
        public string carName { get; set; }
        public bool? carActive { get; set; }
        public string lastUpdate { get; set; }
    }
}

 

image

Next we create a classes folder in the Angular section of the application.

We right-click on the classes folder and select Add then New Item…

image

We select TypeScript Template File, name the file Classes.tst, and click Add.

image

We use the following code:

 

${
    // Enable extension methods by adding using Typewriter.Extensions.*
    using Typewriter.Extensions.Types;
    // This custom function will take the type currently being processed and 
    // append a ? next to any type that is nullable
   string TypeFormatted(Property property)
    {
        var type = property.Type;
        if (type.IsNullable)
        {
            return  $"?";
        }
        else
        {
            return  $"";
        }
    }
}
    // $Classes/Enums/Interfaces(filter)[template][separator]
    // filter (optional): Matches the name or full name of the current item. * = match any, 
    // wrap in [] to match attributes or prefix with : to match interfaces or base classes.
    // template: The template to repeat for each matched item
    // separator (optional): A separator template that is placed between all templates e.g. 
    // $Properties[public $name: $Type][, ]
    // More info: http://frhagn.github.io/Typewriter/
    $Classes(*DTO)[
    export interface $Name {$Properties[
        $name$TypeFormatted: $Type;]
    }
    ]

 

When we save the file, a new file, CarDTO.ts, will be created:

image

It will have the following code:

 

    // $Classes/Enums/Interfaces(filter)[template][separator]
    // filter (optional): Matches the name or full name of the current item. 
    // * = match any, wrap in [] to match attributes or prefix with : to match interfaces or base classes.
    // template: The template to repeat for each matched item
    // separator (optional): A separator template that is placed between all templates e.g. 
    // $Properties[public $name: $Type][,]
    // More info: http://frhagn.github.io/Typewriter/
    
    export interface CarDTO {
        id: number;
        carName: string;
        carActive?: boolean;
        lastUpdate: string;
    }

 

Note:

  • The CarDTO.ts file will be automatically updated whenever the corresponding CarDTO.cs file is updated
  • If we add additional server-side classes to the project, additional TypeScript Angular classes will be created for them
  • To understand how templates are created see the documentation on the Typewriter site.

 

Creating Services

image

Create a controller called CarController.cs in the server-side code section of the project using the following code:

 

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using TypeWriterTest.Models;
namespace TypeWriterTest.Controllers
{
    [Route("api/[controller]")]
    public class CarApiController : Controller
    {
        string strCurrentDateTime = 
            $"{DateTime.Now.ToShortDateString()} {DateTime.Now.ToShortTimeString()}";
        // GET: api/CarApi/GetCars
        [AllowAnonymous]
        [HttpGet("[action]")]
        #region public List<CarDTO> GetCars()
        public List<CarDTO> GetCars()
        {            
            // Collection to hold Cars
            List<CarDTO> colCarDTOs = new List<CarDTO>();
            colCarDTOs.Add(new CarDTO() { id = 1, carName = "Car One", carActive = true, lastUpdate = "" });
            colCarDTOs.Add(new CarDTO() { id = 2, carName = "Car Two", carActive = false, lastUpdate = "" });
            colCarDTOs.Add(new CarDTO() { id = 3, carName = "Car Three", carActive = true, lastUpdate = "" });
            return colCarDTOs;
        }
        #endregion
        // PUT: api/CarApi/1
        [HttpPut("{id}")]
        #region public IActionResult Put([FromRoute] int id, [FromBody] CarDTO CarDTO)
        public IActionResult Put([FromRoute] int id, [FromBody] CarDTO CarDTO)
        {
            CarDTO.lastUpdate = strCurrentDateTime;
            return Ok(CarDTO);
        }
        #endregion
        // POST: api/CarApi
        [HttpPost]
        #region public IActionResult Post([FromBody] CarDTO CarDTO)
        public IActionResult Post([FromBody] CarDTO CarDTO)
        {
            CarDTO.lastUpdate = strCurrentDateTime;
            return Ok(CarDTO);
        }
        #endregion
        // DELETE: api/CarApi/1
        [HttpDelete("{id}")]
        #region public IActionResult Delete([FromRoute] int id)
        public IActionResult Delete([FromRoute] int id)
        {
            return NoContent();
        }
        #endregion
    }
}

 

image

Next we create a services folder in the Angular section of the application.

We create a TypeScript Template File, named Services.tst using the following code:

 

${
    using Typewriter.Extensions.WebApi;
    Template(Settings settings)
    {
        settings.OutputFilenameFactory = file => 
        {
            var FinalFileName = file.Name.Replace("Controller", "");
            FinalFileName = FinalFileName.Replace(".cs", "");
            return $"{FinalFileName}.service.ts";
        };
    }
    // Change ApiController to Service
    string ServiceName(Class c) => c.Name.Replace("ApiController", "Service");
    // Turn IActionResult into void
    string ReturnType(Method objMethod) 
    {
        if(objMethod.Type.Name == "IActionResult")
        {
                if((objMethod.Parameters.Where(x => !x.Type.IsPrimitive).FirstOrDefault() != null))
                {
                    return objMethod.Parameters.Where(x => !x.Type.IsPrimitive).FirstOrDefault().Name;
                }
                else
                {
                    return "void";
                }
        } 
        else
        {
                return objMethod.Type.Name;
        }
    }
    // Get the non primitive paramaters so we can create the Imports at the
    // top of the service
    string ImportsList(Class objClass)
    {
        var ImportsOutput = "";
        // Get the methods in the Class
        var objMethods = objClass.Methods;
        // Loop through the Methdos in the Class
        foreach(Method objMethod in objMethods)
        {
            // Loop through each Parameter in each method
            foreach(Parameter objParameter in objMethod.Parameters)
            {
                // If the Paramater is not prmitive we need to add this to the Imports
                if(!objParameter.Type.IsPrimitive){
                    ImportsOutput = objParameter.Name;
                }
            }
        }
        // Notice: As of now this will only return one import
        return  $"import {{ { ImportsOutput } }} from '../classes/{ImportsOutput}';";
    }
    // Format the method based on the return type
    string MethodFormat(Method objMethod)
    {
        if(objMethod.HttpMethod() == "get"){
            return  $"<{objMethod.Type.Name}>(_Url)";
        } 
        
        if(objMethod.HttpMethod() == "post"){
            return  $"(_Url, {objMethod.Parameters[0].name})";
        }
        if(objMethod.HttpMethod() == "put"){
            return  $"(_Url, {objMethod.Parameters[1].name})";
        }
        if(objMethod.HttpMethod() == "delete"){
            return  $"(_Url)";
        }
        
        return  $"";
    }
}
${
//The do not modify block below is intended for the outputed typescript files... }
//*************************DO NOT MODIFY**************************
//
//THESE FILES ARE AUTOGENERATED WITH TYPEWRITER AND ANY MODIFICATIONS MADE HERE WILL BE LOST
//PLEASE VISIT http://frhagn.github.io/Typewriter/ TO LEARN MORE ABOUT THIS VISUAL STUDIO EXTENSION
//
//*************************DO NOT MODIFY**************************
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http'; 
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
$Classes(*ApiController)[$ImportsList
@Injectable()
export class $ServiceName {
    constructor(private _httpClient: HttpClient) { }        
    $Methods[
    // $HttpMethod: $Url      
    $name($Parameters[$name: $Type][, ]): Observable<$ReturnType> {
        var _Url = `$Url`;
            return this._httpClient.$HttpMethod$MethodFormat
                .catch(this.handleError);
    }
    ]
    // Utility
    private handleError(error: HttpErrorResponse) {
        console.error(error);
        let customError: string = "";
        if (error.error) {
            customError = error.status === 400 ? error.error : error.statusText
        }
        return Observable.throw(customError || 'Server error');
    }
}]

 

image

When we save the template, it will create service file with the following code:

 

//*************************DO NOT MODIFY**************************
//
//THESE FILES ARE AUTOGENERATED WITH TYPEWRITER AND ANY MODIFICATIONS MADE HERE WILL BE LOST
//PLEASE VISIT http://frhagn.github.io/Typewriter/ TO LEARN MORE ABOUT THIS VISUAL STUDIO EXTENSION
//
//*************************DO NOT MODIFY**************************
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http'; 
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import { CarDTO } from '../classes/CarDTO';
@Injectable()
export class CarService {
    constructor(private _httpClient: HttpClient) { }        
    
    // get: api/CarApi/getCars      
    getCars(): Observable<CarDTO[]> {
        var _Url = `api/CarApi/getCars`;
            return this._httpClient.get<CarDTO[]>(_Url)
                .catch(this.handleError);
    }
    
    // put: api/CarApi/${id}      
    put(id: number, carDTO: CarDTO): Observable<CarDTO> {
        var _Url = `api/CarApi/${id}`;
            return this._httpClient.put(_Url, carDTO)
                .catch(this.handleError);
    }
    
    // post: api/CarApi      
    post(carDTO: CarDTO): Observable<CarDTO> {
        var _Url = `api/CarApi`;
            return this._httpClient.post(_Url, carDTO)
                .catch(this.handleError);
    }
    
    // delete: api/CarApi/${id}      
    delete(id: number): Observable<void> {
        var _Url = `api/CarApi/${id}`;
            return this._httpClient.delete(_Url)
                .catch(this.handleError);
    }
    
    // Utility
    private handleError(error: HttpErrorResponse) {
        console.error(error);
        let customError: string = "";
        if (error.error) {
            customError = error.status === 400 ? error.error : error.statusText
        }
        return Observable.throw(customError || 'Server error');
    }
}

 

Complete The Application

image

To demonstrate how the code is consumed, we will create a car folder and add the following code:

car.component.html

 

<h1>Car Sample</h1>
<p *ngIf="!cars"><em>Loading...</em></p>
<table class='table' *ngIf="cars">
    <thead>
        <tr>
            <th> </th>
            <th>Car Name</th>
            <th>Car Active</th>
            <th>Last Update</th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let car of cars">
            <td width="20%">
                <button type="button" (click)="updateCar(car)">Update</button>
                <button type="button" (click)="deleteCar(car)">Delete</button>
            </td>
            <td width="30%"><input type="text" [(ngModel)]="car.carName" name="carName"></td>
            <td width="20%">
                <select [(ngModel)]="car.carActive">
                    <option *ngFor="let stat of status" value={{stat}}>
                        {{stat}}
                    </option>
                </select>
            </td>
            <td width="30%">{{ car.lastUpdate }}</td>
        </tr>
    </tbody>
</table>
<br />
<h4>Add Car:</h4>
<form [formGroup]="carForm" (ngSubmit)="AddCar($event)"
      style="background-color:cornsilk; padding: 12px 20px; width:300px; border:double 1px;">
    <span>Car Name: </span>
    <input formControlName="carName" size="20" type="text">
    <br /><br />
    <span>Car Active: </span>
    <select formControlName="carActive">
        <option *ngFor="let stat of status" value={{stat}}>
            {{stat}}
        </option>
    </select>
    <br /><br />
    <button type="submit">Add Car</button>
</form>

 

car.component.ts

 

import { Component, OnInit } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { CarService } from '../services/Car.service';
import { CarDTO } from '../classes/CarDTO';
@Component({
    selector: 'car',
    templateUrl: './car.component.html'
})
export class CarComponent {
    public cars: CarDTO[] = [];
    public errorMessage: string;
    public status = [
        true,
        false
    ];
    public carForm = this.fb.group({
        carName: ["", Validators.required],
        carActive: ["", Validators.required]
    });
    constructor(
        private _CarService: CarService,
        public fb: FormBuilder) { }
    ngOnInit() {
        this._CarService.getCars().subscribe(
            cars => {
                this.cars = cars;
            },
            error => {
                this.errorMessage = <any>error;
                alert(this.errorMessage);
            });
    }
    AddCar() {
        // Get the form values
        let formData = this.carForm.value;
        let paramCarName = formData.carName;
        let paramCarActive = formData.carActive;
        let NewCar: CarDTO = {
            id: (this.cars.length + 1),
            carName: paramCarName,
            carActive: paramCarActive,
            lastUpdate: ""
        };
        this._CarService.post(NewCar).subscribe(
            returnedCar => {
                // Add the Car to the grid
                this.cars.push(returnedCar);
            },
            error => {
                this.errorMessage = <any>error;
                alert(this.errorMessage);
            });
    }
    updateCar(car: CarDTO) {
        this._CarService.put(car.id,car).subscribe(
            returnedCar => {
                // Get the index of the Car in the grid
                var intCarIndex: number =
                    this.cars.findIndex(x => x.id == returnedCar.id);
                // Update the Car
                if (intCarIndex > -1) {
                    this.cars[intCarIndex].carName = returnedCar.carName;
                    this.cars[intCarIndex].carActive = returnedCar.carActive;
                    this.cars[intCarIndex].lastUpdate = returnedCar.lastUpdate;
                }
            },
            error => {
                this.errorMessage = <any>error;
                alert(this.errorMessage);
            });
    }
    deleteCar(car: CarDTO) {
        this._CarService.delete(car.id).subscribe(
            () => {
                // Get the index of the Car in the grid
                var intCarIndex: number =
                    this.cars.findIndex(x => x.id == car.id);
                // Remove the Car from the grid
                this.cars.splice(intCarIndex,1);
            },
            error => {
                this.errorMessage = <any>error;
                alert(this.errorMessage);
            });
    }
}

 

When we run the application it allows us to perform Create, Read, Update, and Delete functionality.

 

Links

Typewriter

Visual Studio 2017

TypeScript

Keeping your C# and TypeScript models in sync (Angular 4)

Using Typewriter to Strongly-Type Your Client-Side Models and Services (Knockout)

TypeWriter, TypeScript, WebAPI! Oh my!  (AngularJs)

TypeScript codegeneration with Typewriter  (AngularJs)

Download

The project is available at http://lightswitchhelpwebsite.com/Downloads.aspx

You must have Visual Studio 2017 (or higher) installed to run the code.

Tags: Angular 4
Categories:
Microsoft Visual Studio is a registered trademark of Microsoft Corporation / LightSwitch is a registered trademark of Microsoft Corporation