orm comments edit

Chi mi segue su Twitter sicuramente saprà che ultimamente mi sono messo a “giocare” un po’ con ConfORM, e, nello specifico, ho deciso di rimpiazzare FluentNHibernate in Dexter, per far strada al Framework prodotto da Fabio Maulo.

Per chi non lo conoscesse, ConfORM è un Framework che facilità incredibilmente tutta la parte di mapping del nostro dominio - quando si utilizza NHibernate per la persistenza - cambiando totalmente l’approccio; ma andiamo per gradi.

Oggigiorno esistono diversi modi di scrivere il mapping per NHibernate, partendo dal classico e mai datato XML, fino ad arrivare a Framework più recenti come FluntNHibernate, Ddl2Hbm, VisualNHibernate, etc.
Purtroppo questi framework hanno lo stesso approccio, obbligandoci a specificare la corrispondenza di ogni singola property di ciascuna classe di dominio verso il database.

Non conosco i vostri gusti relativamente alla scrittura di codice, ma personalmente ritengo molto noiosa e ripetitiva la fase di stesura del mapping, motivo per cui ConfORM la vince su tutti gli altri.

L’approccio di ConfORM.

Come già accennato ConfORM ha preso totalmente un’altra strada; di fatto inizialmente può lasciare l’utente un po’ spiazzato, ma quando si è capito il funzionamento è sicuramente un viaggio di sola andata, in quanto induce ad abbandonare totalmente il mapping “tradizionale”.
Di fatto quello che è necessario fare è “istruire” ConfORM con le nostre “regole” di sviluppo e di nomenclatura e specificare solo le eventuali eccezioni, lasciando a lui il compito di generare e gestire tutta la fase di mapping.

Per capire meglio il vantaggio, il grafico seguente mostra il Dominio di Dexter che in precedenza era mappato con FluentNHibernate in 27 classi differenti ed ora è mappato in poco più di 20 righe di mapping

 

ClassDiagram1

Maggior Produttività e controllo.

Un altro vantaggio sicuramente interessante è l’aumento di produttività: possiamo aggiungere e togliere classi al nostro dominio senza toccare il mapping, a condizione che queste rispettino le regole stabilite precedentemente.
Quest’aspetto è sicuramente molto interessante perché ci permette di modificare il dominio senza preoccuparci di dover aggiornare il mapping, e riduce il rischio di introdurre errori dovuti ai continui cambiamenti.
Un altro aspetto che adoro è la rigidità che si può introdurre nel lavoro in team, in quanto se qualche sviluppatore non rispetta le regole di mapping prestabilite è obbligato ad andare a dichiarare l’eccezione manualmente e quindi il cambiamento è facilmente identificabile; un esempio banale potrebbe essere la nomenclatura delle tabelle: si è stabilito che sul database esse debbano chiamarsi con il nome della classe di dominio ma al plurare e, se un dev vuol chiamare la tabella in maniera differente è obbligato a gestire lo special case a mano e specificarlo nel mapping.

Performance:

L’utilizzo di ConfORM porta anche vantaggi prestazionali alla nostra applicazione in quanto, a differenza di tutti gli altri Framework di mapping, genera direttamente le classi necessarie a NHibernate per il suo utilizzo, saltando così tutta la fase di parsing del file xml contenente il mapping.
Ovviamente quest’aumento di performance è beneficiabile solo in fase di startup ed è sicuramente apprezzabile quando si ha a che fare con domini piuttosto corposi.
Per capire meglio il funzionamento di ConfORM rispetto al classico mapping o ad altri Framework, riporto qui un grafico “rubato” dal blog di Fabio che spiega perfettamente il perché dell’aumento di performances.

 

confORM

Conclusioni:

Ovviamente seguiranno altri post che mostreranno la parte più tecnica di ConfORM, ma per chi non volesse aspettare riporto alcuni link utili:

  • Download di ConfORM – Download.
  • Una serie di post su ConfORM è disponibile qui.

Enjoy your mapping.

.net comments edit

Spessissimo, quando mi trovo a dover scrivere dei test, ho la necessità di creare delle istanze di classi contenenti dei dati finti, in modo da verificarne il corretto funzionamento.

Di fatto, se proviamo ad immaginare di dover testare un metodo ForEach per una classe IEnumerable(vedi qui), sicuramente nel test dobbiamo creare una lista contente gli elementi da iterare.
Anche se semplice, la creazione di un set di informazioni finte, anche tramite classi “helper”, può risultare una fase noiosa e ripetitiva.
Grazie ad un consiglio di Fabio ho provato questo framework, che ci aiuta tantissimo nella creazione di liste - ma anche di singole istanze - con dati fake.

Il funzionamento è piuttosto banale ed intuitivo: di fatto si ha una composizione fluent che ci permette di coprire i principali scenari.

Per capire il suo potenziale provate ad immaginare di dover creare una lista di 10 elementi…con NBuilder si può ottenere lo stesso risultato con una sola riga di codice! J

var posts = Builder<Post>.CreateListOfSize(10).Build();


Ovviamente si possono specificare anche criteri un po’ più “strong”, forzando il valore di una specifica proprietà o addirittura alternando un valore all’interno della lista.

var posts = Builder<Post>.CreateListOfSize(10)
                .WhereAll()
                .Have(p => p.Username = "imperugo")
                .Build();

Un'altra feature che trovo interessantissima è la possibilità di persistere l’oggetto su di un nostro repository, quindi invocare un metodo passando il dato creato. Chi scrive integration test troverà sicuramente questa feature molto vantaggiosa.

//Definisco il servizio di persistenza da invocare
BuilderSetup.SetCreatePeristenceMethod<Post> (postService.SaveOrUpdate);

//Persisto l'oggetto fake
Builder<Post>.CreateNew().Persist();

Ovviamente il framework offre numerosissime altre features, che trovate qui.

Direi un must.

Enjoy it.

asp.net comments edit

Nel weekend scorso ho deciso di implementare l’OpenSearch all’interno del mio blog in modo da offrire un servizio in più ed imparare una cosa nuova. In pratica lo scopo era di creare un provider di ricerca per i principali browser di navigazione come Internet Explorer, Firefox e Chrome. L’implementazione è piuttosto banale: basta creare un HttpHandler - o un file statico nel caso in cui le informazioni non necessitino di una gestione dinamica - contenente un set d’informazioni in formato XML, aggiungere il link a tale risorsa nell’header della pagina, ed il gioco è fatto; il browser penserà poi a recuperare in automatico le informazioni e a “proporvi” il provider di ricerca da aggiungere. Il codice dell’HttpHandler è veramente banale e lo potete vedere qui di seguito:

[csharp] public class OpenSearchHandler : HttpHandlerBase { private readonly ISiteConfigurationService siteConfigurationService; private readonly IUrlBuilderService urlBuilder;

public OpenSearchHandler ()
{
    siteConfigurationService = IoC.Resolve&amp;lt;ISiteConfigurationService&amp;gt; ();
    urlBuilder = IoC.Resolve&amp;lt;IUrlBuilderService&amp;gt; ();
}

public OpenSearchHandler ( ISiteConfigurationService siteConfigurationService , IUrlBuilderService urlBuilder )
{
    this.siteConfigurationService = siteConfigurationService;
    this.urlBuilder = urlBuilder;
}

public override void ProcessRequest ( HttpContextBase context )
{
    SiteConfigurationDTO configuration = siteConfigurationService.GetConfiguration ();

    StringBuilder sb = new StringBuilder ( &quot;&amp;lt;OpenSearchDescription xmlns=\&quot;http://a9.com/-/spec/opensearch/1.1/\&quot;&amp;gt; &quot; );
    sb.AppendFormat ( &quot;&amp;lt;ShortName&amp;gt;{0}&amp;lt;/ShortName&amp;gt;&quot; , configuration.BlogName );
    sb.AppendFormat ( &quot;&amp;lt;Description&amp;gt;{0}&amp;lt;/Description&amp;gt;&quot; , configuration.SeoConfiguration.DefaultDescription );
    sb.AppendFormat ( &quot;&amp;lt;Image height=\&quot;16\&quot; width=\&quot;16\&quot; type=\&quot;image/vnd.microsoft.icon\&quot;&amp;gt;{0}{1}&amp;lt;/Image&amp;gt;&quot; , urlBuilder.SiteWithHttp () , &quot;Images/favicon.ico&quot; );
    sb.AppendFormat(&quot;&amp;lt;Url type=\&quot;text/html\&quot; template=\&quot;{0}blog/search?q={1}\&quot; /&amp;gt; &quot;, urlBuilder.SiteWithHttp(), &quot;{searchTerms}&quot;);
    sb.AppendFormat(&quot;&amp;lt;Url type=\&quot;application/rss+xml\&quot; template=\&quot;{0}blog/search?q={1}\&quot; /&amp;gt; &quot;, urlBuilder.SiteWithHttp(), &quot;{searchTerms}&quot;);
    sb.Append ( &quot;&amp;lt;/OpenSearchDescription&amp;gt;&quot; );

    context.Response.ContentEncoding = Encoding.UTF8;
    AddHeaders ( &quot;text/xml&quot; , 30 , sb.GetHashCode () );

    context.Response.Write ( sb.ToString () );
}

} [/csharp]

Mentre per quanto riguarda l’header della pagina html, è sufficiente inserire il seguente markup html: [xml]&lt;link type="application/opensearchdescription+xml" rel="search" title="Il blog di ugo lattanzi" href="/opensearch.axd"/&gt;[/xml] A questo punto il risultato dovrebbe essere più o meno quello riportato negli screenshot seguenti:

Internet Explorer:

imageimageimage

FireFox:

imageimageimage

Nota: Chi fosse interessato può esporre anche il suggest nella ricerca, restituendo un set di informazioni in formato json (vedi qui).

Ciauz

asp.net comments edit

Ultimamente mi è capitato uno strano errore che mi ha fatto “scervellare” (passatemi il termine) per individuarne la causa, poi la soluzione si è presentata davanti agli occhi ed era più semplice di quel che pensavo (anche se devo ammettere che il messaggio di errore non era di aiuto); ma partiamo dall’inizio.

Un paio di settimane fa ho sviluppato un plugin per Dexter che non fa altro che mostrare informazioni provenienti da vari feeds rss; nel mio caso specifico sono feeds RSS dei principali social network a cui partecipo, ed il mio scopo era di creare una pagina che li aggregasse tutti insieme in modo da riassumere le mie ultime attività (per chi fosse interessato al funzionamento può vedere il risultato finale qui).

I plugin in Dexter non sono altro che delle semplici librerie caricate automaticamente a runtime ed aggiunte all’application domain principale (ancora per poco ); al contrario degli altri plugin, come il like di facebook, questo non ne voleva sapere di partire, restituendo sempre il seguente errore:

Server Error in '/' Application.
Could not load file or assembly 'Dexter.Plugins.LifeStream' or one of its dependencies. An attempt was made to load a program with an incorrect format.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.BadImageFormatException: Could not load file or assembly 'Dexter.Plugins.LifeStream' or one of its dependencies. An attempt was made to load a program with an incorrect format.
Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Assembly Load Trace: The following information can be helpful to determine why the assembly 'Dexter.Plugins.LifeStream' could not be loaded.

Ora io ero certo che l’applicazione si trovasse nel path corretto e che tutto funzionasse a norma; di fatto in locale il plugin sembrava perfetto, eppure doveva esserci un fattore che ne impediva il funzionamento nel server di produzione.
Indagando un po’ a fondo e cercando errori simili in rete sono risalito al problema, scoprendo che il tutto era dovuto alla compilazione della libreria in questione che non era a 64bit come richiesto dal server di produzione.

Purtroppo non so per quale motivo, ma il nuovo progetto del plugin aggiunto a Visual Studio aveva la compilazione abilitata solo per i 32bit e non “Any CPU” come mi aspettavo, e l’application pool in produzione era configurato per eseguire soltanto codice compilato per i 64bit e quindi si rifiutava (giustamente) di caricare l’assembly, bloccando il flusso corretto di funzionamento dell’applicativo.
Al contrario nella mia macchina di sviluppo era tutto funzionante perché nella configurazione di IIS era stata impostata l’opzione “Enable 32-bit Application” negli “Advanced Settings” dell’application pool, come mostrato dallo screenshot seguente.

SNAGHTML20b8c76f

Come potete vedere il problema è piuttosto banale e facilmente risolvibile se non per il “non bel” messaggio di notifica.
64-bit Rulez!

asp.net comments edit

Chi lavora con le applicazioni web si sarà sicuramente imbattuto nell’eccezione HttpRequestValidationException scatenata dall’engine di ASP.NET quando un client cerca di effettuare il submit di informazioni potenzialmente pericolose, aka codice html, verso il server.
Personalmente ritengo questa una comodissima feature in quanto ci consente di “alleggerire” la nostra applicazione nell’analisi dei dati in ingresso e demandare il tutto ad ASP.NET; al contrario, se si vuole gestire questa casistica secondo dei propri requirements, è possibile disattivarla e prendersi carico e responsabilità del fatto che ciò che arriverà dal client non è stato validato da nessuno.

Dando per assodato che, dal mio punto di vista, questa funzione dovrebbe rimanere abilitata, quello che vorrei specificare in questo post è come mostrare all’utente un messaggio “friendly” che lo invita ad inserire del plaintext nel campo di input. L’idea è nata analizzando il log del mio blog, in cui ho trovato una miriade di tentativi di commenti che cercavano di inserire link (praticamente tutto spam), ma senza successo grazie a questo blocco.

Questo è possibile in diversi modi, come con l’utilizzo di httpmodule, applicationError, etc., ma in applicazioni MVC preferisco utilizzare il meno possibile HttpModule (vuoi perchè in IntegratedMode passa veramente di tutto) e gestire la cosa dal controller.
In Dexter ho un ControllerBase da cui ereditano tutti i controller, dove, oltre ad esporre delle ActionResult custom, ho la gestione dei log per ciò che riguarda la parte di MVC, in soldoni ho l’override del metodo OnException dove butto dentro la mia logica di logging, etc.

Quando una qualsiasi eccezione riguardante una richiesta MVC viene sollevata dal framework, si può essere certi che verrà intercettata e verrà invocato quel metodo, permettendoci di gestirla a nostro piacimento.

protected override void OnException(ExceptionContext filterContext)
{
    HttpException httpException = filterContext.Exception as HttpException;

    if (httpException is HttpRequestValidationException)
    {
        Logger.Info ( httpException.Message , httpException );

        var currentUrl = filterContext.RequestContext.HttpContext.Request.Url.AbsolutePath;

        filterContext.ExceptionHandled = true;

        filterContext.Result =  RedirectToAction("HttpRequestValidation", "Errors", new
                                                                    {
                                                                 aspxerrorpath = currentUrl
                                                                    });
    } else if (httpException != null && httpException.GetHttpCode() == 404)
        Logger.Info(httpException.Message, httpException);
    else if (filterContext.Exception is HttpAntiForgeryException)
        Logger.Info(filterContext.Exception.Message, filterContext.Exception);
    else
        Logger.Error("Generic Exception", filterContext.Exception);
}

Come potete vedere non è nulla di fantascientifico ed è più o meno quello che si andrebbe a fare con un’applicazione WebForm classica, fatta eccezione per l’utilizzo della proprietà ExceptionHandled, che notifica a MVC che siamo noi a prenderci in carico il Result da quel momento in poi, e di fatto subito dopo si va ad effettuare un redirect.

Il risultato è questo.

asp.net comments edit

L’annuncio arriva direttamente dal blog di Scott Guthrie, anche se il download era apparso sui server Microsoft già da alcune ore: sta di fatto che MVC 3 Preview 1 è stato rilasciato, e lo potete scaricare direttamente qui.
Anche la versione 3 sembra percorrere quanto già fatto dalla versione 2, ossia evolvere quanto di già buono c’è senza stravolgere la struttura, quindi non aspettatevi di trovare grandissimi cambiamenti all’interno di questa release.

Tra le novità è stato incluso Razor, un view engine “csharp like” che va ad affiancarsi al view engine già presente, permettendo così di avere View scritte con differenti sintassi; un’altra novità molto interessante è la presenza dell’IServiceLocator, che personalmente ritenevo una mancanza in MVC2 (in dexter abbiamo implementato un qualcosa di simile).
In linea di massima tutta la parte di Dependency Injection è stata migliorata e di fatto ora è possibile andare a “giocare” con controller, viewengine, views, validation providers, model meta data provider, model binder, e chi più ne ha più ne metta.

Sono presenti anche altre novità di minor rilievo come ViewData dinamico, che sfrutta la keyword dynamics di c# 4 e di conseguenza vincola l’utilizzo di MVC3 all’ultima release del .NET Framework.

Direi che di argomenti e spunti per poter parlare e provare MVC3 ce ne sono, e sicuramente un confronto di Razor con Spark non tarderà ad arrivare.

Ciauz

eventi comments edit

Da pochi giorni si è concluso l’evento GroundZero di DotNetLombardia, dove ho avuto l’opportunità di parlare un po’ delle novità introdotte con il .NET Framework 4.0 per il mondo web, quindi di ASP.NET, MVC2 ed AJAX.
Ringrazio tutta l’organizzazione e le persone presenti per aver scelto di passare una passare una giornata a parlare di tecnologia.

Purtroppo  non ho avuto modo di assistere a tutte le sessioni della giornata (molto bravo Federico); in particolar modo mi avrebbe fatto piacere assistere la sessione del mio super Desk Neighbor Matteo e di Giuseppe che sicuramente sarebbe riuscito a farmi capire un po’ Sharepoint.

Il download delle slide è disponibile qui

various comments edit

È un po’ che non faccio un post su Dexter, ma questo non vuol dire che il progetto è fermo, anzi: ci stiamo lavorando tanto e nel dev team sono apparsi nomi nuovi, alcuni anche di un certo peso, il che mi fa molto piacere.
Detto ciò, ieri sera ho aggiornato la versione attuale del mio blog all’ultima release della trunk, che apporta una serie di migliorie ed ovviamente un gran numero di nuove features.

In primis è stato fortemente potenziato il supporto per Windows Live Writer che ora gestisce nativamente Tagging (con intellisense), Categorie Multiple (con sottocategorie), Abstract, Slug Customizzati e, dulcis in fundo, offre la possibilità di creare dinamicamente le proprie pagine (la mia pagina about è stata creata con WLW) con la possibilità di avere un vero e proprio Tree di pagine (maggiori info qui).

Alcuni screenshot:

WIndows Live Writer 001WIndows Live Writer 002WIndows Live Writer 003WIndows Live Writer 004


Per chi è un fan di WLW i complimenti vanno al buon Alessandro che ha dedicato molto del suo tempo libero a realizzare questa parte.
Oltre a questo, da come si era intuito dai miei ultimi post, è possibile realizzare skin anche utilizzando SparkViewEngine; ovviamente rimane la possibilità di scriverle in maniera “classica” o, se si preferisce, mista.
L’attuale skin è il porting della precedente in Spark e sembra girare bene, a dimostrazione dell’ottimo prodotto.

Di migliorie ce ne sono davvero tante, dalle notifiche con template, incluse di master page e localizzazione, fino ad arrivare ai post schedulati, autochiusura dei commenti per i post più vecchi di x giorni, OpenSearch, plugin, etc.
Importanti novità sono “in canna”: nelle prossime settimane prenderà luce la prima beta dotata di un sistema di autoinstallazione, configurazione ed upgrade automatico, e, da lì a breve, si aggiungeranno molte altre cose che ora non posso svelare.

Per chi fosse interessato ad un’eventuale migrazione è pronto un tool per l’import da Wordpress, e a breve da BlogML e RSS.

Che dire, un mega grazie a tutti quelli che mi hanno scritto e supportato in questa pazza avventura.
Ciauz

asp.net comments edit

Nel post precedente ho mostrato come è possibile ridurre il numero di righe di codice presenti all’interno della skin quando ci si trova a dover gestire dei blocchi di if per la visualizzazione di porzioni di Html. Ovviamente all’interno delle nostre Views non ci troviamo soltanto ad utilizzare i vari if/elseif/else, ma sicuramente andremo a creare delle iterazioni che ci permettono di mostrare un set di contenuti, come potrebbe essere l’elenco delle ultime news.

L’approccio è lo stesso, ed in questi due blocchi di codice (engine classic e spark) possiamo notare come è possibile evitare la sintassi di apertura e di chiusura del ciclo:

<%for (int i = 0; i < Model.Categories.Count; i++){%>
    <li class="category">
        <%= Model.Categories[i].Name%>
    </li>
<%}%>
<li class="category" each="var Category in Model.Categories">
    ${Category.Name}
</li>

Ovviamente volendo è possibile usare una sintassi leggermente differente, e quindi senza l’attributo each per un tag container: in questo caso è sufficiente utilizzare il tag for, come mostrato di seguito:

<for each="var Category in Model.Categories">
    <li class="category">
        ${Category.Name}
    </li>
</for>

Come potete vedere in questa situazione, anche se non si ha un vantaggio nel numero di righe scritte, si ha comunque un vantaggio in leggibilità del codice.

Sicuramente in alcuni casì c’è però la necessità di essere a conoscenza dell’esatta posizione in cui ci si trova all’interno del ciclo,  del numero totale di elementi, oppure di sapere se si è all’inizio o alla fine dello stesso: il problema è risolto grazie a Spark, che mette a disposizione, tramite un’apposita name convention, delle proprietà che ci restituiscono queste informazioni, come mostrato di seguito:

<for each="var Category in Model.Categories">
    ItemIndex = ${CategoryIndex}
    TotalItems = ${CategoryCount}
    IsFirstItem = ${CategoryIsFirst}
    IsLastItem = ${CategoryIsLast}
</for>

Come potete vedere basta aggiungere in coda all’item corrente (category nell’esempio) un suffisso, il resto lo fa Spark.

Enjoy it.