Il principale vantaggio dell'uso di Asp.Net MVC è l'isolamento della view dai controller che ci permette di rendere altamente testabili le nostre applicazioni Web. Spesso però, scrivendo le nostre view facciamo riferimento esplicitamente ad altre pagine o risorse esterne, il che purtroppo scolpisce nel codice chi sia ad esempio la pagina "Home" o "Chi Siamo".
In Asp.Net MVC per risolvere gli url in modo che rispettino le regole di routing impostate per l'applicazione o l'area di cui ci stiamo occupando si utilizza un Helper chiamato UrlHelper, disponibile a livello di view mediante l'oggetto Url
.
Possiamo quindi estendere questa classe perché ci fornisca dei metodi che eseguano il wrap degli nostri URL mediante appositi metodi e possiamo farlo senza scomodare l'ereditarietà del linguaggio ad oggetti che utilizziamo, perchè il .Net Framework ci mette a disposizione un potente mezzo adatto ai nostri scopi: gli extension methods.
Un extension method in C# non è altro che un metodo statico di una classe statica che ha come parametro la classe da estendere preceduta dall'operazione this
. Ciò darà l'illusione che il metodo appartenga effettivamente alla classe in questione anche se l'autocompletamento chiarisce subito la differenza utilizzando un'icona speciale per indicarli:
A compile-time il compilatore semplicemente sostituirà la chiamata al metodo della classe con la chiamata al metodo statico che abbiamo realizzato. L'intera libreria Linq è costituita da extension methods, quello in figura 7 ad esempio, è proprio un extension method di Linq to Object.
Supponiamo di dover realizzare un piccolo sito Web di presentazione aziendale in cui siano presenti le classiche pagine "Chi Siamo", "Dove Siamo", "Servizi", "Contattaci" e naturalmente la home page: possiamo realizzare una classe statica che contenga le nostre estensioni della classe UrlHelper
:
public static class UrlHelperExtension
{
public static string Home(this UrlHelper helper)
{
return helper.Content("~/");
}
public static string ChiSiamo(this UrlHelper helper)
{
return helper.Content("~/ChiSiamo");
}
public static string DoveSiamo(this UrlHelper helper)
{
return helper.Content("~/DoveSiamo");
}
public static string Servizi(this UrlHelper helper)
{
return helper.Content("~/Servizi");
}
public static string Contattaci(this UrlHelper helper)
{
return helper.Content("~/Contattaci");
}
}
Il menu di navigazione, di solito contenuto nella Master Page della nostra applicazione, potrà usare tali estensioni per realizzare i link alle pagine:
<div id="menu">
<ul>
<li><a href="<%= Url.Home() %>">Home</a></li>
<li><a href="<%= Url.ChiSiamo() %>">Chi siamo</a></li>
<li><a href="<%= Url.DoveSiamo() %>">Dove siamo</a></li>
<li><a href="<%= Url.Servizi() %>">Servizi</a></li>
<li><a href="<%= Url.Contattaci() %>">Contattaci</a></li>
</ul>
</div>
Che sarà a renderizzato con il seguente codice HTML:
<div id="menu">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/ChiSiamo">Chi siamo</a></li>
<li><a href="/DoveSiamo">Dove siamo</a></li>
<li><a href="/Servizi">Servizi</a></li>
<li><a href="/Contattaci">Contattaci</a></li>
</ul>
</div>
Abbiamo in questo modo isolato in una classe statica gli url a cui ci riferiamo nel nostro menu, ma si può fare la stessa cosa anche con immagini, script e qualsiasi risorsa linkata dalle nostre pagine.