orm comments edit

In questi giorni sto lavorando parecchio ad un’applicazione che usa Oracle come repository e NHibernate come framework di persistenza. Essendo questa un’applicazione “delicata” ho necessità di creare una serie di integration test che mi “garantiscano” il corretto funzionamento, in modo da non avere spiacevoli sorprese in fase post deploy.

Letta così la questione non presenta particolari criticità, ma ho dovuto affrontare un nuovo scenario riguardante Oracle e la sua gestione degli indici.

Prima di entrare nel dettaglio tecnico vorrei puntualizzare che la soluzione da me adottata è la conseguenza di una totale inesperienza relativamente al mondo Oracle, potrebbe quindi esistere una strada migliore e più corretta per arrivare alla soluzione (magari se la conoscete, datemi qualche consiglio Open-mouthed smile).

Fatta tale premessa provo a descrivere un po’ lo scenario. Nella mia installazione interna all’azienda ho un solo database engine di Oracle che contiene al suo interno l’applicazione di sviluppo, quella di test ed infine quella di quality assurance. Quindi, lato database, ho tre schema/utenti ben differenti denominati rispettivamente Dev, Test e QA, ed ognuno di questi ha le proprie tabelle con i propri dati, come mostrato dalla tabella seguente:

dev

test

QA

dev.users

test.users

qa.users

dev.roles

test.roles

qa.roles

dev.usersinroles

test.usersinroles

qa.usersinroles


Essendo l’applicazione in uno stato di sviluppo più o meno avanzato, il database delle linea dev non subisce molti “restyling”, al contrario del database dei test che viene cancellato e ricreato ad ogni test.

Il mio problema è nato proprio durante la fase di “drop & create” dello schema: questo viene creato correttamente, ma poi la procedura di NHibernate non completa correttamente il tutto perché, al contrario di quanto avviene per le tabelle, gli indici non sono legati ad uno specifico schema, sollevandomi una brutta eccezione del tipo “nome oggetto già utilizzato” (riferendosi all’indice che si stava cercando di creare).
Se si riosserva la tabella riportata in precedenza si può facilmente intuire che l’univocità del nome della tabella è data dalla combinazione dello schema con il nome della tabella stessa. Purtroppo o per fortuna (direi più per fortuna) questa “combo” non esiste per gli indici, il che si traduce nel dover creare indici con nomi differenti per ogni “environment” in quanto trasversali all’interno del database engine.

L’indice IX_ItemType non è dev.IX_ItemType!

La mia configurazione di NHibernate creava automaticamente degli indici per alcuni scenari (nello specifico per il “Table Per Class Hierarchy”) in modo da aiutare il database nell’eseguire le query. Con il supporto del buon Fabio ho creato un Applier per ConfORM (in realtà ho fatto copia ed incolla di quello esistente) che mi permette di stabilire un prefisso per tutti gli indici, in modo da avere un risultato tipo il seguente:

  • IX_MyIndex;
  • IX_Test_MyIndex;
  • IX_QA_MyIndex;

Una volta creato l’applier mi è bastato effettuare una merge dello stesso e, come per magia, tutti i test sono diventati verdi.
Per chi fosse interessato posto il codice dell’applier di ConfORM

public class DiscriminatorIndexNameApplier : IPatternApplier<Type, IClassAttributesMapper> {
    private readonly IDomainInspector domainInspector;
    readonly string indexPrefix;

    public DiscriminatorIndexNameApplier ( IDomainInspector domainInspector, string indexPrefix ) {
        this.domainInspector = domainInspector;
        this.indexPrefix = indexPrefix;
    }

    #region IPatternApplier<Type,IClassAttributesMapper> Members

    public bool Match ( Type subject ) {
        return domainInspector.IsTablePerClassHierarchy ( subject );
    }

    public void Apply ( Type subject, IClassAttributesMapper applyTo ) {
        applyTo.Discriminator ( dm => dm.Column ( cm => cm.Index ( indexPrefix + subject.Name + "EntityType" ) ) );
    }

    #endregion
}

 

e per il suo utilizzo:

IPatternsAppliersHolder patternsAppliers = ( new ImperugoPatternsAppliersHolder ( orm , NHConfiguration.Instance.IndexPrefix ) )
    .Merge ( new ConfORM.DiscriminatorValueAsEnumValuePack <Person, PersonDiscriminatorMap> ( orm ) )
    .Merge ( new ConfORM.DiscriminatorValueAsEnumValuePack <View , ViewDiscriminatorMap> ( orm ))
    .Merge ( new ConfORM.DiscriminatorIndexNameApplier ( orm, NHConfiguration.Instance.IndexPrefix ) );


dove l’ultima riga cambia la naming convention degli indici leggendo il prefisso dal file di configurazione. Enjoy!

web dev comments edit

La chiusura delle specifiche dell’HTML5 è prevista intorno al 2014, ma la percentuale di penetrazione sul mercato ha sicuramente raggiunto un livello che “impone” a noi dev web di dare un’occhiata un po’ più da vicino a cosa ci offre questa nuova tecnologia.
Al community tour di Milano avrò modo di parlare un po’ più in dettaglio di alcune caratteristiche, di fare un po’ il punto su quanto è già utilizzabile dell’HTML5 e su ciò che verrà, facendo un po’ di chiarezza sui punti più bui.
Quindi “save the date” 3 maggio c/o Microsoft Italia. L’iscrizione gratuita è disponibile qui.

Vi aspetto!

eventi comments edit

MIX11_BB_SeeYouAt_2_thumbSi è conclusa da poche ore la prima giornata del MIX11, e le novità di cui parlare sono già tante. Essendo io un web addicted mi soffermerò principalmente sulle novità riguardanti il mondo “www”, quindi per le novità su WP7 dovrete leggere altrove Smile.

Nella keynote si è ribadito quanto l’HTML5 sia il futuro del web e quanto Microsoft stia investendo su questa tecnologia. La stessa società lo ha dimostrato presentando e rilasciando pubblicamente la prima Platform Preview di Internet Explorer 10, che potete scaricare gratuitamente qui. La demo, visibile direttamente dal blog del team qui, ha dimostrato quanto Internet Explorer sia un passo avanti rispetto alla concorrenza sul fronte delle performance. Quest’incredibile lavoro da parte del team mi fa sempre più pensare che HTML5, e nello specifico l’engine di IE, saranno parte integrante della prossima release di Windows (magari si potranno sviluppare applicazioni HTML5 per Windows 8).

Un’altra importante novità è il rilascio dei Visual Studio Tool per ASP.NET MVC 3, che vanno ad aggiornare i template di Visual Studio e ad aggiungere nuove funzioni. Nello specifico ora si ha la possibilità di specificare se il progetto MVC andrà a fare uso dell’HTML5 e, nel caso si opti per tale tecnologia, si avrà direttamente a disposizione la libreria Modernizr 1.7, che aiuta l’utente a creare applicazioni HTML5 cross browser. Rimanendo in tema di librerie javascript, anche jquery è stato aggiornato all’ultima release e, grazie a NuGet, sarà possibile aggiornarlo direttamente da Visual Studio in maniera del tutto automatica. Passando un po’ alla parte di backend, i nuovi tool includono Code First di ADO.NET Entity Framework 4.1 e lo scaffolding per MVC, confermando un po’ la tendenza di andare a sovrapporsi un po’ a Ruby On Rails.

Il download ovviamente è disponibile sia dal Web Platform Installer che tramite il download diretto da qui.

asp.net comments edit

Internet Information Service (IIS) versione 7.x offre la possibilità di configurare il proprio sito un po’ più in autonomia rispetto alle versioni precedenti.

Quando parlo di autonomia mi riferisco alla possibilità di cambiare tutti quei parametri che normalmente richiedono l’accesso alla console di IIS sul server, come compressione dei files, static content, mime types, etc. ; e proprio dell’abilitazione dei mime-type volevo parlare quest’oggi.

Prima di vedere come aggiungere nuovi mime-type alla configurazione di IIS, è giusto capire il perché un webserver non consenta l’accesso ad alcune estensioni di default, bloccando di conseguenza alcuni file a noi utili.
La risposta si racchiude in una sola parola: Sicurezza.

Di fatto, se non ci fosse questo tipo di blocco, un utente potrebbe scaricare anche files con dati sensibili, tipo .mdb, .inc, etc., ossia tutti quei files che il client non dovrebbe mai vedere J.

Capito il perché esistono questi blocchi, è necessario capire come abilitarne alcuni non accessibili normalmente.
A partire dalla versione 7.x di IIS siamo abituati a vedere una nuova sezione nel file di configurazione: “system.webServer”, sezione questa che viene ignorata nel caso l’applicazione stia girando in una versione antecedente alla 7.x (quindi non spaventiamoci se ci troviamo su Windows 2003 ed abbiamo questa strana sezione J).

Al suo interno possiamo impostare parecchi parametri, tra i quali ci sono i mime-type. Questa procedura è veramente molto semplice, ci basta infatti aggiungere poche righe di XML per avere ciò che ci serve, come mostrato dal codice seguente:

<system.webserver>
    <staticcontent>
        <mimemap fileextension=".mp4" mimetype="video/mp4">
        <mimemap fileextension=".m4v" mimetype="video/m4v">
    </mimemap></mimemap></staticcontent>
</system.webserver>

È molto importante fare attenzione a cosa ci è consentito fare e cosa no da IIS. Infatti non è detto che l’amministratore di sistema voglia offrire la possibilità allo sviluppatore di cambiare alcuni settaggi. Infatti è necessario che le “Delegation” di IIS siano impostate in “Allow” per le sezioni che ci interessano.

Chi fosse interessato all'argomento può buttare un occhio qui http://learn.iis.net/page.aspx/94/delegating-administration/

IIS Rulez!

web dev comments edit

Dopo il deploy di Dexter, finalmente torno a fare un po’ di post tecnici (speriamo che duri Smile) e spero di raccontare un po’ delle tante “figosità”- passatemi il termine - che ho inserito nell’ultima versione, prima fra tutte il supporto a Windows Azure.
Non che ci siano cose difficili da fare lato tecnologico per migrare una piattaforma ad Azure, ma alcune cose, se pur semplici, non è detto che siano scontante. Quando mi è stato chiesto il supporto al cloud di casa Microsoft, la prima domanda che mi sono posto è stata: come modifico la soluzione e come aggiungo un qualcosa di preesistente?

I passaggi sono veramente pochi e semplici; per prima cosa ci basta aggiungere alla Solution un nuovo progetto di tipo “Windows Azure Cloud Service” e non associare nessun web/worker role al nuovo progetto. Da questo momento la nostra solution dovrebbe contenere il nuovo progetto e, una volta cliccato con il tasto destro, si ha la possibilità di associare un progetto esistente presente nella solution come webrole del nostro Cloud Service.
Gli screenshot seguenti mostrano la proceura passo passo.

29-03-2011 23-29-42 29-03-2011 23-30-2329-03-2011 23-30-36

29-03-2011 23-33-3929-03-2011 23-33-58

Una volta completati questi passaggi è necessario che la nostra applicazione referenzi le tre assembly indispensabili al funzionamento sul cloud:

  • Microsoft.WindowsAzure.Diagnostics;
  • Microsoft.WindowsAzure.ServiceRuntime;
  • Microsoft.WindowsAzure.StorageClient;

Come ultimo passaggio è necessario inserire una classe, “WebRole.cs” nel nostro caso, nel progetto web per far sì che l’environment di sviluppo di Azure possa verificare il corretto funzionamento dell’istanza.

La classe dovrà contenere il seguente codice:

 

using System.Linq;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;

namespace Dexter.Web.UI.Azure {
    public class WebRole : RoleEntryPoint {
        public override bool OnStart ( ) {
            // For information on handling configuration changes
            // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
            RoleEnvironment.Changing += RoleEnvironmentChanging;

            CloudStorageAccount.SetConfigurationSettingPublisher ( ( configName , configSetter ) => configSetter ( RoleEnvironment.GetConfigurationSettingValue ( configName ) ) );

            return base.OnStart ( );
        }

        static void RoleEnvironmentChanging ( object sender , RoleEnvironmentChangingEventArgs e ) {
            // If a configuration setting is changing
            if ( e.Changes.Any ( change => change is RoleEnvironmentConfigurationSettingChange ) ) {
                // Set e.Cancel to true to restart this role instance
                e.Cancel = true;
            }
        }
    }
}


Da questo momento in poi possiamo fare il run dell’applicazione, ed il tutto dovrebbe girare sotto “Azure”.

Soon altri post del tipo “come migrare un’applicazione ad Azure senza referenziare Azure Smile

various comments edit

Chi segue i commit di Dexter su codeplex, sicuramente avrà notato che il progetto non è morto, tutt’altro.

In questi giorni, oltre al solito lavoro su Dexter, ho lavorato al porting del blog di QuiBrowser che, da ieri, gira sulla “mia” piattaforma. La versione installata è ben diversa da quella utilizzata nel mio blog: di fatto l’ho praticamente “riscritta”, con conseguente ritardo (l’ennesimo) nel rilascio di una build.
Tra le novità introdotte in questa versione (di cui parlerò in seguito) c’è la skin, realizzata sfruttando le principali caratteristiche messe a disposizione dall’HTML5: canvas, tag semantici, trasparenze, ombre, font custom, etc.

Il risultato:

23-03-2011 22-34-24

 

Per chi fosse interessato all’argomento consiglio di buttarci un occhio.
Ci sono un po’ di problemini con il server (tempi di risposta alti), ma presto passerà ad Azure Open-mouthed smile


Un super mega grazie ad Alessandro che mi ha aiutato come sempre in questa folle impresa: un mito!

eventi comments edit

Il 15 marzo in Italia si terrà il Web Camps, organizzato da Microsoft Italia, al quale ho la fortuna di partecipare come speaker; nello specifico terrò due sessioni, la prima riguardante HTML5 e CSS3, la seconda un’introduzione ad Orchard, il nuovo CMS Open Source di casa Microsoft.

 logo_MicrosoftWebCamps

Per gli appassionati del web direi che è un must! Agenda ed iscrizioni sono disponibili qui

various comments edit

Recentemente sono stato contattato da due società di Bari che stanno facendo recruiting di dev su tecnologia Microsoft. I requirements sono i principali: .NET Framework, Visual Studio etc.

Chi è interessato può contattare me direttamente qui.

Ciauz

asp.net comments edit

Stufo dei soliti switch per recuperare il content type di un file, mi sono deciso a dare una sbirciata in rete per verificare se esistesse un qualcosa che mi potesse restituire il content type dato un file name.
Ovviamente, come quasi sempre in questi casi, qualcun’altro si è posto la mia stessa domanda ed ha trovato una soluzione a tale problema Smile.

Di fatto, nel .NET Framework è possibile utilizzare la classe Registry per andare a recuperare la nostra informazione, come mostrato dall’extension method seguente:

/// <summary>
///     Retrieve the mimetype for the specified filename.
/// </summary>
/// <param name = "fileName">Name of the file.</param>
/// <returns></returns>
public static string GetMimeType (this string fileName ) {
    string mime = "application/octetstream";
    string ext = Path.GetExtension ( fileName ).ToLower ( );
    RegistryKey rk = Registry.ClassesRoot.OpenSubKey ( ext );
    if ( rk != null && rk.GetValue ( "Content Type" ) != null ) {
        mime = rk.GetValue ( "Content Type" ).ToString ( );
    }
    return mime;
}

Ciauz

FONTE : http://petrocel.wordpress.com/2008/01/09/how-to-get-the-content-typemimetype-of-a-file-c/