13 Dic

Applicazioni desktop multi-piattaforma

Programming Node.JS

Lo sviluppo di applicazioni mobile ci ha abituato ad utilizzare svariati framework (ad esempio Ionic, PhoneGap, Apache Cordova e Xamarin) che permettono di sviluppare applicazioni mobili e di rilasciarle su diverse piattaforme mobili (Android, Windows Phone, iOS). Ma e’  possibile sviluppare un’applicazione desktop con l’obbiettivo di rilasciarla su differenti sitemi operativi (Windows, Linux e Mac OS)? Subito pensiamo a Java e allo slogan che accompagna da sempre questo linguaggio di programmazione: “write once, run anywhere“.

Oltre a Java ci sono altre tecnologie, più o meno datate, che permettono lo sviluppo di applicazioni desktop multi-piattaforma. Tra queste vanno ricordate: Adobe Air, Haxe, Qt. Tuttavia tutte necessitano di competenze specifiche e richiedono team di sviluppo altamente specializzati.

Ci sono invece dei veri e propri framework per lo sviluppo desktop multi-piattaforma che si poggiano su standard e linguaggi tipici dello sviluppo web. Questi framework permettono di sviluppare applicazioni desktop a partire da conoscenze pregresse basate su HTML5, CSS3, Javascript e su tutte quelle librerie e moduli disponibili per il web. Tra i più utilizzati troviamo:

Caratteristica comune è quella di appoggiarsi a Node.js e ad un’istanza di Chromium  per il rendering della user interface.

Tra le tre soluzioni, Electron, pur essendo il framework più recente, annovera diversi progetti di rilievo tra i quali Atom (GitHub), Visual Studio Code (Microsoft), Nuclide (Facebook), Slack, Hive e MongoTron. Punto di forza, oltre allo sviluppo di applicazioni desktop utilizzando tecnologie web, è  quello di combinare Chromium e Node.js in un unico runtime permettendo di distribuire lo stesso pacchetto sui tre sistemi operativi desktop più diffusi: Windows, Linux e Mac OS.

Electron per funzionare non richiede quindi la presenza di virtual machine o interpreti sul sitema operativo di destinazione. L’applicazione puo’ essere distribuita rilasciando i binari di Electron insieme ai file sorgenti dell’applicazione o pacchetizzando il tutto in archivi asar.

Per maggiori dettagli e riferimenti riguardo all’architettura di Electron, nonche’ alcuni esempi interessanti, potete visitare:

11 Mag

R (Statistical programming) – Le basi

R

Dopo aver introdotto R nell’articolo “Introduzione a R (Statistical programming)“, si descrivono ora le nozioni base del linguaggio e si introduce l’ambiente di sviluppo. Il presente articolo è il primo di una serie dedicata a R che descriverà nei dettagli la sintassi e le principali caratteristiche del linguaggio.

Affronteremo ora  i seguenti argomenti:

  1.  La command-line interface (CLI), o più brevemente la console  di R;
  2. I workspace e le variabili;
  3. I principali ambienti di sviluppo

La console di R

Dopo aver installato R, seguendo le istruzioni dal sito ufficiale della community di R (r-project.org), è possibile utilizzarne la console. Questa permette di lanciare comandi in ambiente R, proprio come il bash di linux, il prompt di windows o la CLI di powershell.

La console di R presenta alcune similitudini con il bash di GNU/Linux.  Per chi è abituato a sviluppare in ambiente Windows, si ricorda che in R i paths al file system vengono sempre  editati con il forward slash (/) invece del back slash (\). A titolo di esempio, si consideri il comando  setwd che permette di definire la posizione di un workspace di R. Per indicare il path al workspace si usa il forward slash nella destinazione. In alternativa, si puo’ utilizzare il doppio simbolo di backslash (\\), il primo dei quali viene interpretato come comando di escape da R.

> setwd("c:/tmp/R") # o anche: setwd("c:\\tmp\\R")

Alcuni comandi e shortcut utili sono i seguenti:

  • quit() o q() per uscire dalla shell;
  • lo shortcut CTRL+L corrisponde al clear della console;
  • getwd() ritorna il path al workspace nel quale si lavora;
  • setwd("path") imposta il path al workspace;
  • ls() ritorna tutte le variabili create in una sessione di R .
  • rm([variabili]) rimuove tutte o alcune delle variabili della sessione corrente

La console interagisce direttamente con l’engine di R. E’ quindi possibile far stampare calcoli base come somme o sottrazioni, o anche semplici letterali:

> 1+2
[1] 3
> 1-100
[1] -99
> "Hello Darwin!"
[1] "Hello Darwin!"

I workspaces e le variabili

I workspaces in R rappresentano l’ambiente di lavoro. Nel workspace  vengono salvati gli oggetti della sessione in uso(vettori, matrici, ecc.). Alla fine della sessione di lavoro si puo’ decidere di salvare o meno l’immagine della sessione in uso che verrà ricaricata automaticamente al successivo lancio di R.

E’ possibile preservare sessioni diverse in directories diverse. I comandi principali per interagire con i workspaces sono i seguenti:

# visualizza la directory corrente del workspace
getws()

# configura la directory nella quale salvare la sessione
setws("physical path")

# salva l'immagine del workspace nella directory correntemente in uso in un file con estensione .RData
save.image()

#ricarica un'immagine precedetemnte salvata
load("miofile.RData")

In R si possono allocare i dati in variabili. R assegna sempre un oggetto alla variabile, per questo non è necessario dichiarare il tipo della variabile come nei linguaggi dichiarativi. Quindi, in R il tipo della variabile rispecchia il tipo dell’oggetto assegnato. R viene considerato un linguaggio “weakly typed” intendendo che non è necessario dichiarare esplicitamente il tipo della variabile e neppure convertire esplicitamente un tipo in un altro. Questa definizione è spesso contestata in quanto fuorviante. E’ più corretto definire R come un linguaggio nel quale i tipi vengono liberamente interpretati in fase di run time.

Gli oggetti che si possono assegnare ad una variabile sono fondamentalmente:

  • Vectors
  • Lists
  • Matrices
  • Arrays
  • Factors
  • Data Frames

Nel proseguo di questa serie di articoli dedicati ad R si analizzeranno nel dettaglio le caratteristiche e le proprietà di ogni singolo oggetto. Per il momento si riportano  qui sotto i tipi principali:

  • Numeric:  valori numerici
  • Integer: valori numerici interi
  • Double: valori numerici a doppia precisione (virgola mobile)
  • Logical:  valori booleani
  • Character:  stringhe di caratteri
  • Raw: serie di bytes
  • Complex: numeri complessi

Per verificare il tipo di dato contenuto in una variabile R si utilizza la funzione is.[datatype]([variable]). La funzione globale class() ritorna invece il tipo della variabile. Qui di seguito alcuni esempi:

#assign numeric to variable
> x <- 10.5
> x
[1] 10.5
> class(x)
[1] "numeric"

#test numeric type
> is.double(x)
[1] TRUE
> is.integer(x)
[1] FALSE
> is.numeric(x)
[1] TRUE

#assign raw bytes to variable
> y <- raw(2)
> y
[1] 00 00
> class(y)
[1] "raw"
#assign string to variable
> z <- 'this is a test'
> z
[1] "this is a test"

#test type
> is.character(z)
[1] TRUE
> is.numeric(z)
[1] FALSE

Come riportato precedentemente, in R i tipi delle variabili vengono liberamente interpretati in fase di runtime. E’ comunque possibile convertire esplicitamente una variabile o un letterale da un tipo all’altro con la funzione as.[tipo]([letterale|variabile]):

> x <- 10
> x  is.integer(x)
[1] FALSE
> is.double(x)
[1] TRUE
> y <- as.integer(10)  
> is.integer(y)
[1] TRUE

Gli script in R, R Studio e risorse online

E’ sempre possibile salvare e caricare scripts in ambiente R. Questo lo si puo’ fare sia con la console interattiva che con l’ambiente di sviluppo di riferimento, ovvero R Studio. Nella configurazione di default R Studio presenta quattro riquadri nei quali è possibile:

  1. Editare e lanciare uno script
  2. Visualizzare le funzioni, le variabili d’ambiente e lo storico delle azioni
  3. Utilizzare una console integrata
  4. Navigare la repository del progetto, visualizzare i plots, ecc.

R-Studio

Online esistono ambienti R interattivi nei quali si possono lanciare scripts o caricare interi progetti. Tra i molti si segnalano R-Fiddle e Coding Ground con l’executer per R.

05 Mag

Introduzione a R (Statistical programming)

R

R e’ un linguaggio di programmazione ideale per il computo statistico e la generazione di plot grafici.  R sta rapidamente diventando un riferimento per i data scientists. Questo articolo descrive brevemente le potenzialità di R e i suoi campi applicativi.

R in sintesi

R è un ambiente di sviluppo software libero indirizzato alla data analysis e alla statistical analysis. L’obbiettivo di R è quello di raccogliere una grande varietà di tecniche statistiche facilitandone il plotting grafico. La statistica è quella disciplina che studia quantitaivamente e qualitativamente un particolare fenomeno in modo non deterministico, ovvero senza conoscerne le cause a priori.

Lo sviluppo della piattaforma è gestito da una comunità molto attiva. La piattaforma offre strumenti per la data manipulation, il calcolo statistico e la grafica. L’ambiente puo’ essere esteso includendo packages esterni sviluppati dalla stessa comunity.

Vantaggi

  • R è open source e libero;
  • E’ semplice generare grafici da calcoli statistici;
  • Estesa riproducibilità attraverso gli scripts;
  • Sono disponibili svariate estensioni libere fornite dalla community (packages);
  • E’ possibile utilizzare una CLI implementata ad hoc per R.

Svantaggi

  • R è semplice da imparare ma alquanto complesso da “dominare”;
  • Per chi non è un programmatore esperto, la linea di comando puo’ incutere timore;
  • La velocità con la quale si possono generare scripts in R puo’ portare ad una difficile manutenzione;
  • Il codice, se mal scritto, puo’ risultare lento in esecuzione.

Riferimenti e risorse

  1. The R Project for Statistical Computing
  2. Quick R
  3. R-bloggers
  4. Programming with Big Data in R

IDE and tools

  1. R Studio
  2. R Open
  3. Orange
  4. Rattle
  5. Deploy R

Online editors

  1. Coding Ground R
  2. R-Fiddle

 

01 Mar

Le convenzioni definite nel framework ASP.NET MVC

Programming - ASP.NET MVC

Rieccoci a scrivere di ASP.NET MVC e del suo pattern Model-View-Controller. Vengono qui descritte le principali convenzioni da seguire durante lo sviluppo dell’applicazione web.

HomeController

Per convenzione l’HomeController è il punto di partenza dell’applicazione MVC. In un nuovo progetto Visual Studio crea una route di default seguendo questa convenzione. E’ sempre  possibile modificare a posteriori questa route di default nel file Global.asax.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace MvcApplication1
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default",
                "{controller}/{action}/{id}",
                new { controller = "Home", action = "Index", id = "" }
            );

        }

        protected void Application_Start()
        {
            RegisterRoutes(RouteTable.Routes);
        }
    }
}

 Models

Per convenzione, i Models vengono sempre riposti nella cartella ~/Models.

Controllers

Per convenzione, i Controllers vengono riposti nella cartella ~/Controllers. Le classi Controller hanno i nomi terminanti in “Controller”. Si prenda ad esempio la classe HomeController. Quando si utilizzano gli HTML Helper methods di Razor, per convenzione si specifica il nome senza suffisso (nel caso sopre “Home”). Il framework MVC appenderà in automatico la desinenza “Controller” nella ricerca della classe.

Views

Per convenzione, Views  e Partial Views vengono riposte nella cartella ~/Views/[ControllerName].

 Naming convention per View e azioni

Le View sono associate alle azioni attraverso una convenzione nominale. Quindi, ad esempio, se l’azione di un Controller Home è definita come Index, il framework MVC associerà la View  a partire dal file ~/View/Home/Index.[ext]. Nel caso non dovesse trovare il file in questione, lo cercherà in seconda istanza nella cartella Shared, ovvero ~/View/Shared/Index.[ext]. Le estensioni permesse saranno quelle mappate su  IIS o Web.Config.

Quindi, per convenzione, le View  prendono il nome dell’azione e vengono create in una cartella col nome del Controller.

Naming convention per i Layout

Per convenzione ai file di Layout viene sempre anteposto il prefisso_“.  Ad esempio,  _Layout.

Layout di default

Se nella View non viene specificato un Layout tramite la direttiva di Razor @Layout, il framework MVC assume il file ~/Views/Shared/_Layout.cshtl come Layout di default. Questa convenzione di default  puo’ tuttavia essere modificata nel ~/Views/_ViewStart.cshtml cambiandone il nome del file mappato dalla direttiva Razor @Layout.

Contenuti statici e template grafici

I contenuti statici come immagini, file CSS e altri vengono sempre riposti nella cartella Content.

Default request root

Per convenzione una chiamata alla root del sito viene reindirizzata verso l’azione Index dell’HomeController. Ad esempio, se http://www.sviluppoeweb.it  fosse realizzato in ASP.NET MVC, la chiamata alla home del sito verrebbe veicolata dall’HomeController verso l’azione Index e rendendo la View  ~/Views/Home/Index.cshtml.

Cartelle di sistema

Esistono cartelle convenzionali in ASP.NET. Il framework ASP.NET MVC ne eredita alcune e ne implementa di nuove. In particolare:

  • ~/App_Data: questa cartella contiene fonti dati private alla web application (xml di configurazione, db, csv, ecc). I file contenuti in questa cartella sono protetti e non accessibili pubblicamente dal sito.
  • ~/App_Start: contiene i file di configurazione principali, come le Routes, i Filters e i Bundles
  • ~/bin: contiene gli assembly compilati
  • ~/Content: contiene i file statici e i template grafici
  • ~/Controllers: contiene i Controllers
  • ~/Models: contiene i Models
  • ~/Scripts: contiene le librerie Javascript
  • ~/Views: contiene le Views, le Partial Views e i Layout
  • ~/Views/Shared: contiene le Views, le Partial Views e i Layout condivisi
  • ~/Areas: contiene le Areas, una tecnica per suddividere l’applicazione in moduli distinti
  • ~/App_GlobalResources: contiene i resource files globali (per le Web Forms)
  • ~/App_LocalResources: contiene i resource files locali (per le Web Forms)

File di sistema

Come per le cartelle, esistono anche alcuni file di sistema:

  • ~/Views/Web.Config: questo file di configurazione previene che le views vengano servite  da IIS
  • ~/Global.asax: la classe globale delle applicazioni ASP.NET (eventi di inzializzazione, shutdown, gestione delle eccezioni a livello globale, ecc. )
  • ~/Web.Config: file di configurazione dell’applicazione
24 Feb

Generare file XML con Node.js

Programming Node.JS

Come sappiamo XML (eXtensible Markup Language) è un metalinguaggio utilizzato per definire linguaggi di markup. In parole più semplici, XML serve a creare nuovi linguaggi definendone le regole. I punti di forza di XML sono:

  • semplicità: è basato su una sintassi caratterizzata da poche regole,
  • interoperabilità: è supportato da una grande varietà di linguaggi di programmazione e tecnologie,
  • estensibilità: gli elementi definiti possono essere estesi e adattati ad altri utilizzi.

Oggi XML è principalmente utilizzato per modellare la struttura di documenti e dati. Possiamo dire che lo ritroviamo un po’ ovunque: nei file di configurazioni delle  applicazioni , nei messaggi che si scambiano i servizi web, nelle interazioni tra database eterogenei, nelle repository di dati salvate su file, ecc.

A volte è necessario generare file XML a supporto della logica delle nostre applicazioni.  Per questo scopo ci vengono in aiuto Node.js e il relativo modulo XMLBuilder.

L’utilizzo di XMLBuilder è estremamente semplice. Il suo punto di forza  è la facilità con la quale si possono mappare in un oggetto javascript le regole e i dati del file XML che si vuole generare.

Per utilizzare XMLBuilder bisogna innanzitutto installare node.js. Il package manager di node permette scaricare il modulo XMLBuilder tramite il comando:

> npm install xmlbuilder

Una volta  installato XmlBuilder in locale ci possiamo “divertire” a generare file XML. Ad esempio, salviamo il seguente codice javascript nel file text.js

var builder = require('xmlbuilder');
var xml = builder.create('root')
  .ele('first')
    .ele('second', {'type': 'attribute text'}, '2nd node text')
  .end({ pretty: true});

console.log(xml);

Lanciamo Node puntando al file javascript:

d:\tmp\xmlbuilder> node test.js
<?xml version="1.0"?>
<root>
  <first_node>
    <second_node type="child">some node text</second_node>
  </first_node>
</root>

Come si vede il modulo XmlBuilder ha generato il file XML seguendo le direttive definite nel file test.js

La cosa più interessante di XmlBuilder è la capacità di generare file XML a partire da oggetti javascript. Ad esempio, per ottenere lo stesso risultato, possiamo modificare il file test.js come segue:

var builder = require('xmlbuilder');
var root = builder.create('root');

var obj = {
  first: {
    second: {
    '#text': '2nd node text',
    '@type': 'attribute text'
    }
  }
};

root.ele(obj);
console.log(root.doc().end({ pretty: true}))

Il file XML viene generato da un oggetto javascript (obj nello script). La direttiva ‘#text’ indica di associare del testo al nodo mentre ‘@’ indica di inserire un attributo. XmlBuilder è molto flessibile e personalizzabile. Il risultato prodotto é identico al precedente:

d:\tmp\xmlbuilder> node test.js
<?xml version="1.0"?>
<root>
  <first>
    <second type="attribute text">2nd node text</second>
  </first>
</root>

Si possono concatenare più oggetti, come nell’esempio sottostante:

var builder = require('xmlbuilder');
var root = builder.create('root');

var obj1 = {
  persona: {
    nome: "Mario",
    '@age': 35,
    indirizzo: {
    citta: "Milano"
    },
    telefono: [
      { '#text': "348-123467", '@type': 'casa' }, 
      { '#text': "348-123567", '@type': 'ufficio' }
    ],
    id: function() {
      return 1;
    }
  }
};

var obj2 = {
  persona: {
    nome: "Maria",
    '@age': 57,
    indirizzo: {
      city: "Bari"
    },
    telefono: [
      { '#text': "345-123467", '@type': 'casa' }, 
      { '#text': "345-123567", '@type': 'ufficio' }
    ],
    id: function() {
      return 2;
    },
    figlio: [
      {nome: "Luigi", '@age': 25},
      {nome: "Giuseppe", '@age': 23},
      {nome: "Antonio", '@age': 19},
    ]
  }
};

root.ele(obj1);
root.ele(obj2);

console.log(root.doc().end({ pretty: true}))

Si ottiene il seguente risultato:

d:\tmp\xmlbuilder>node test.js
<?xml version="1.0"?>
<root>
  <persona age="35">
    <nome>Mario</nome>
    <indirizzo>
      <citta>Milano</citta>
    </indirizzo>
    <telefono type="casa">348-123467</telefono>
    <telefono type="ufficio">348-123567</telefono>
    <id>1</id>
  </persona>
  <persona age="57">
    <nome>Maria</nome>
    <indirizzo>
      <city>Bari</city>
    </indirizzo>
    <telefono type="casa">345-123467</telefono>
    <telefono type="ufficio">345-123567</telefono>
    <id>2</id>
    <figlio age="25">
      <nome>Luigi</nome>
    </figlio>
    <figlio age="23">
      <nome>Giuseppe</nome>
    </figlio>
    <figlio age="19">
      <nome>Antonio</nome>
    </figlio>
  </persona>
</root>

La cosa più interessante di XmlBuilder è la completa integrazione di javascript nella definizione della struttura dei file XML. Questo permette di gestire logiche particolari quando generiamo l’output, soprattutto grazie all’utilizzo di funzioni javascript.

Happy programming!

 

23 Gen

Microsoft si cambia: benvenuto .NET Core 1.0

Programming - .NET Core 1.0

I recenti rilasci di Windows 10 e  Visual Studio 2015 hanno introdotto moltissime novità e miglioramenti sulle piattaforme di sviluppo Microsoft. Si pensi alla Universal Windows Platform (UWP), al nuovo browser EDGE,  ad una console dei comandi migliorata, ad un package managment tool (OneGet) integrato nella powershell, a Windows 10 IoT per Rasperry Pi e Arduino, e molto molto altro ancora.

Ma con tutte queste novità, a chi non è venuto qualche dubbio? Una delle cose che hanno creato non poche perplessità  riguardava le differenze tra il .NET Framework 4.6 e il .NET Framework 5.  Molti inizialmente hanno creduto che la versione 5 fosse la release successiva alla 4.6 e che quindi quest’ultima diventasse obsoleta.

In verità, come spiega molto bene Scott Hanselman nel suo blog,  la versione 5 non rappresenta una versione successiva di .NET ma una vera e propria build indipendente supportata da librerie e moduli spesso diversi rispetto a quelli della versione 4.6.

Nel 2014 Microsoft annunciò l’intenzione di rendere il framework .NET “open source and cross platform” con il rilascio di Visual Studio 2015. Per realizzare questo intento sono state riviste e a volte risviluppate ex-novo parte delle librerie .NET.

Quote - Phil Karlton

La scelta del nome del nuovo framework però non è stata azzeccatissima, creando non poca confusione tra gli sviluppatori. Per questo motivo Microsoft ha deciso di rinominare la “piattaforma” 5 (o 2015), e tutti i progetti che vi si poggiano sopra, in Core 1.0. Questo cambiamento dovrebbe evidenziare un nuovo ciclo di sviluppo incentrato su principi open source e cross platform.  Non si tratta quindi della continuazione di un “brand” già affermato, supportato, stabile e in pieno sviluppo.

Il .NET Framework 5 viene quindi rinominato in .NET Core 1.0 e tra i progetti più seguiti ASP.NET 5 prende il nome di  ASP.NET Core 1.0, Entity Framework 7 diventa Entity Framework Core 1.0,  ASP.NET Identity 3 cambia in ASP.NET Identity Core 1.0.

Questa immagine può aiutare a inquadrare le nuove “naming conventions” e a fugare ogni dubbio.

19 Gen

Bundling in un progetto ASP.NET MVC

Programming - ASP.NET MVC

Google Translate traduce la parola “bundle”  in “impacchettare”. Niente di più azzeccato per introdurre il bundling in un’applicazione ASP.NET MVC.

Oggi sviluppare siti e applicazioni per il web risulta un’attività estremamente complessa. Esistono svariati moduli open source facilmente integrabili durante lo sviluppo. Si pensi alle migliaia di librerie javascript disponibili (JQuery, Backbone.js, Knockout.js… e chi più ne ha più ne metta) o ai frameworks CSS (tra i quali spiccano Bootstrap e Zurb Foundation).

A questi moduli si aggiungono i tools di supporto allo sviluppo:  generatori di codice (Sass, Less, Coffescript, Handlebars, Jade,…), task manager (ad esempio Grunt, Gulp, Broccoli, Browserify), package manager (Nuget, Npm, Bower, ecc.) e molti altri ancora.

Quando bisogna integrare moduli esterni in un progetto web, gli sviluppatori si affidano a procedure di bundling. Queste ci assistono nell’ottimizzazione del codice.

Tra gli aspetti più importanti del bundling ci sono l’aggregazione e l’ottimizzazione dei diversi sorgenti in un unico file evitando di sovraccaricare le comunicazioni client-server (I/O overhead). Nello sviluppo web, al bundling si associa infatti un processo di “minificazione” con lo scopo di ridurre le dimensioni dei dati scambiati tra le chiamate. Grazie al bundling vengono eliminate le parti superflue o ridondanti di un file, come ad esempio spazi, commenti, ritorni a capo, ecc.

Nei progetti ASP.NET MVC le procedure di bundlig vengono gestite in tre passi:

  1. Configurazione: si istruisce l’applicazione su come combinare e comprimere i file;
  2. Registrazione: si informa l’applicazione dell’esistenza dei bundles;
  3. Reference: si referenziano i bundles nelle View di progetto e quindi nel frontend.

Vediamo nel dettaglio queste tre fasi.

Configurare i bundles

La configurazione dei bundles viene attuata nel file BundleConfig.cs riposto nella cartella  App_Start . La configurazione consiste nel definire e aggiunegere i bundles alla tabella dei bundles.

Nell’esempio qui sotto vengono inclusi tre file javascript  e due fogli di stile:

 
public static void RegisterBundles(BundleCollection bundles)
{
  //Scripts js
  var myBundleScript = new ScriptBundle("~/bundles/main-js");
  myBundleScript.Include(
    "~/Scripts/cls/clsRollingDiv.js",
    "~/Scripts/cls/clsRollingBanner.js",
    "~/Scripts/main-dev.js");

  //Cascade Styles
  var myBundleCss = new StyleBundle("~/bundles/main-css");
  myBundleCss.Include(
    "~/Content/css/css1.js",
    "~/Content/css/css2.js");
  
  //Aggiungo a BundleTable
  bundles.Add(myBundleScript);
  bundles.Add(myBundleCss);
}

Da notare che, a seconda del tipo di file, vengono utilizzate due diverse classi .NET: ScriptBundle per i file javascript e StyleBundle per i fogli di stile.

Il metodo Include  può essere sostituito dal corrispettivo IncludeDirectory che comprenderà tutti i file presenti in una cartella evitando così di elencare i file singolarmente. In entrambi i casi, alla chiamata viene passato il path dei file che si vogliamo impacchettare.

Il simbolo ~ rappresenta la root  di progetto. Questo shortcut risulta comodissimo quando passiamo da un ambiente di sviluppo ad uno di produzione. A titolo di esempio, durante lo sviluppo lo shorcut puo’ indicare una root del tipo http://localhost:1234/js/[files] mentre in produzione i file vengono ricercati in http://www.miosito.it/Scripts/[files]. Questo switch viene gestito autonomamente da ASP.NET.

Registrare i bundles

Terminata la configurazione, si passa alla registrazione dei bundles. Questa avviene nella procedura  Application_Start del file  Global.asax del nostro progetto ASP.NET MVC:

  protected void Application_Start()
    {
      AreaRegistration.RegisterAllAreas();
      [...]
      BundleConfig.RegisterBundles(BundleTable.Bundles);
    }

Con il semplice comando BundleConfig.RegisterBundles tutti i bundles vengono inclusi nella BundleTable e registrati nel progetto.

Referenziare i bundles

L’ultimo step consiste nel referenziare i bundles nelle View del nostro progetto MVC. I bundle devono quindi essere configurati pensando al loro reale utilizzo nel frontend e  nelle pagine web.

Per i file molto utilizzati (come ad esempio le librerie Bootstrap in un progetto responsive) è meglio referenziare i bundle nelle View condivise (Shared). E’ invece preferibile isolare i file meno utilizzati in bundle indipendenti  e richiamali nelle singole View. Nell’esempio sotto, richiamiamo un bundle secondario in una View non condivisa:

    
<!DOCTYPE html>
<html class="no-js" lang="en">
<head>
  <meta charset="utf-8" />
  [...]
  @Styles.Render("~/bundles/secondary-css")
</head>
<body>
  [...]
  @Scripts.Render("~/bundles/secondary-js")
</body>
</html>

Testare il comportamento dei bundles

Ora che abbiano capito come funzionano i bundle,  proviamo a testarne il comportamento. Per il test ipotizziamo di aver creato un bundle per le librerie di JQuery. Lanciamo Visual Studio e analiziamo le chiamate HTTP avvalendoci di Firefox e Firebug.

Notiamo subito che l’ottimizzazione dei file avviene solo quando simuliamo l’ambiente di produzione – quindi col parametro debug=false . Nella figura si nota l’impachettamento e l’ottimizzazione delle librerie JQuery in un ipotetico ambiente di produzione:bundles_jquery_prod

Quando lanciamo il progetto in modalità sviluppo – debug=true –  le librerie vengono restitutite senza alcuna ottimizzazione così da semplificare l’eventuale debugging. E infatti, nell’esempio proposto, viene inoltrato il file originale contenuto nella cartella degli Scripts della nostra applicazione ASP.NET MVC:bundles_jquery_debug

Conclusioni

Una corretta impostazione dei bundle comporta notevoli vantaggi, ovvero:

  1.  Ridurre le chiamate HTTP grazie all’aggregazione dei file;
  2. Ridurre le dimensioni dei file, e quindi il traffico, grazie al processo di “minificazione”;
  3. Caching dei dati inoltrati.

Il caching è particolarmente interessante. In un’applicazione ASP.NET MVC il processo di bundle setta l’header HTTP Expires ad un anno da quando il bundle è stato creato.  Quando si naviga verso una pagina precedentemente visitata non viene quindi inoltrato alcun dato ma vengono utilizzati i dati conservati nella cache del browser.

A livello statistico, Microsoft dichiara notevoli miglioramenti quando si introduce il bundling in un’applicazione:

Uso Con Bundle Senza Bundle Variazione
File Requests 9 34 256%
KB Inviati 3.26 11.92 266%
KB Ricevuti 388.51 530% 36%
Tempo Attesa 510 MS 780 MS 53%
Riferimento: Microsoft ASP.NET Blog

La tabella mostra tutta la convenienza di utilizzare procedure di bundling nelle nostre applicazioni ASP.NET MVC. Buona programmazione!

 

11 Gen

Quando l’informatica aiuta a combattere la povertà

Social - Taking initiative

Una delle storie più commoventi che abbia letto in rete è quella di Eric Elliott. Dopo essere stato obbligato a vendere casa, Eric si ritrova senza un soldo e costretto a girovagare ospitato dagli amici.

Nonostante le avversità, Eric non si perde d’animo e riesce a mettere a rendita quello che gli riesce meglio: sviluppare in Javascript. Grazie alla sua passione e a una grande forza d’animo trova lavoro e mette alle spalle il periodo di crisi.

Il lieto fine fa sicuramente piacere. Ma cosa mi ha emozionato maggiormente in questa storia? Eric fa tesoro della sua esperienza e comincia a promuove il proprio modello nella comunità dei senzatetto. L’approccio non può che essere da programmatore: identificato un problema comune si cerca una soluzione ad ampio spettro.

L’idea è semplice ma efficace, quasi geniale. Eric decide di scrivere un libro di Javascript indirizzato a tutti coloro che vogliono uscire da una condizione di svantaggio. Lo pubblica online insieme ad una serie di training gratuiti per i senzatetto. Inizia una campagna su Kickstarter per sponsorizzare la creazione di nuovi corsi e per coprirne i costi.

Dopo il successo di tutte queste iniziative, Eric lancia il sito JSHomes.org per aumentare la consapevolezza di un problema che ci riguarda tutti molto da vicino.

Nella migliore tradizione open source, il sito diventa spunto per la creazione di una piattaforma dedicata che cerca di coinvolgere il maggior numero di volontari possibili a sostegno dell’illuminante idea di Eric.

Condivido questa bellissima iniziativa che dimostra come una condizione di disagio possa trasformarsi in una storia di successo.

Storia pubblicata su Medium.com il 6 Novembre, 2015

10 Gen

Microsoft termina il supporto ai .NET Framework 4, 4.5 e 4.5.1

System - Microsoft .NET

Il 12 Gennaio 2016 terminerà il supporto alle versioni 4.0, 4.5 e 4.5.1 del .NET Framework. Per continuare a ricevere supporto tecnico e update di sicurezza, Microsoft raccomanda di aggiornare i vari progetti alla versione piu’ recente 4.5.2.

La versione 4.6 rilasciata di recente introduce importanti novità nel framework e, se possibile, potrebbe essere la miglior scelta in eventuali migrazioni di  versione.

Tutte le versioni precedenti alla 4, ed in particolare la  2.x e la 3.5.x, continueranno invece ad essere supportate.

 

04 Gen

Hello world!

Benvenuti

In questo spazio vorrei condividere la mia passione per la tecnologia e la programmazione.  Da anni mi diletto a sporcarmi le mani con diversi linguaggi di programmazione, componenti hardware e, piu’ di recente, con sensori e altre diavolerie tecnologiche. Ho trasformato questa passione in professione e oggi mi interesso di startup e innovazione.

In questo blog vorrei condividere alcune esperienze legate al mio lavoro e passione. Cercherò di restituire alla rete (con la quale sarò sempre in debito) alcune di quelle nozioni apprese durante il lungo viaggio che mi ha portato ad aprire questo blog.