Migrazioni 1.1–> 3.5, #sapevatelo


 

Negli ultimi mesi mi sto occupando della migrazione di un applicativo client server dalla versione 1.1 alla versione 3.5. Per mia sfortuna il codice originale è stato scritto in VB.Net e non ci sono le intenzioni per migrarlo a c#.

Tra giovedì e venerdì ho perso "x" ore nel cercare di individuare un baco che proprio non aveva voglia di farsi stanare, finché qualcuno (che in parte aveva già effettuato la migrazione di parte del codice) mi ha inidirizzato correttamente:

Problema:

VB.Net + Persone non propriamente attente al codice hanno riempito I sorgenti di :

if str is String.Empty

Questo, in ottica 1.1 controllava se la stringa era vuota. In compilazione, il FW 3.5 non da nessun tipo di errore (naturalmente), ma veniamo alla parte più subdola. Compilando e facendo girare l'applicazione in debug (sempre 3.5) non viene sollevata nessuna eccezione, il codice continua a fare esattamente quello che faceva prima e tutto "Sembra" funzionare correttamente.

Facciamo finalmente il deploy nei nostri server di integration, e non funziona più nulla, quello snippet non torna lo stesso risultato che torna in debug.

Non so cosa succeda, se è qualche SP del framework installato sulle macchine di DEV e non su quella di Integration (anche se sembra proprio di no), ho escluso il deploy a 64 bit (non funziona nemmeno se viene compilato a 32bit) e non ho una risposta al "Perchè non funziona", sta di fatto che non funziona.

Conclusione:

Se state facendo una migrazione di codice di VB1.1 in VB3.5 e chi ha scritto in precedenza il codice era solito usare quel costrutto ... controllate!!!

author: Gianluca Gravina | posted @ lunedì 11 ottobre 2010 09:33 | Feedback (0)

Sono tornato a bloggare e fatemi fare un paio di prove :)


Giusto perché è passato più di un anno dagli ultimi post, devo prendere un po' la mano con Live Writer :) e provare l'integrazione con Twitter :)

author: Gianluca Gravina | posted @ lunedì 4 ottobre 2010 13:53 | Feedback (0)

First Impressions


In questi giorni ho avuto la possibilità di "giocare" con un telefonino Android che ho consigliato per l'acquisto, con non poco interesse personale, a mia moglie. Il telefono in questione è un LG GT540 Optimus, telefono acquistato per soli 200 €.

Le impressioni, da possessore di un IPhone 3G devo ammettere che sono ancor più stupito, fa tutto quello che deve fare, in maniera egregia, se devo trovare un difetto, bhé, lo screen non è così responsivo come quello del melafonino, ma me lo aspettavo.

Per ora Android batte IPhone (3G), e visto il prezzo, nettamente ! Aspetto solo WP7, sono MOLTO curioso e mi piacerebbe averne uno per le mani al più presto !

author: Gianluca Gravina | posted @ lunedì 4 ottobre 2010 13:46 | Feedback (0)

First NHDay


Finalmente, dopo tanto tempo, rimetto mano al mio blog, il motivo ? Sabato mi /ci aspetta una (spero) fantastica conferenza con un super tema centrale, Il mio caro amato NHibernate.

Avrò l’occasione di conoscere gente e soprattutto di rivedere qualcuno che ha (giustamente) di lasciare l’Italia e andarsene all’estero :)

Ci si vede a Bologna :) (http://nhday.eu/)

author: Gianluca Gravina | posted @ lunedì 4 ottobre 2010 13:35 | Feedback (0)

Fluent NHibernate Step by Step


In questo Post / articolo, cercherò di mostrare passo per passo come creare una prima bozza di DataAccess utilizzando NHibernate con FluentNH per la configurazione e per elminare la produzione di quei “fastidiosi” file xml di configurazione dei mapping.

A seguire altri post sullo stesso argomento che mostreranno via via mapping più complessi.

Partiamo con la modellazione delle classi con cui vogliamo lavorare, partendo con un esempio semplicissimo con una sola tabella “USER”

Come prima cosa vediamo di seguire il pattern repository per l’accesso ai dati sfruttando i Generics, creiamo la nostra entità di dominio

   1: public class User
   2: {
   3:     public virtual int Id { get; set; }
   4:     public virtual string Name { get; set; }
   5:     public virtual string SurName { get; set; }
   6: }

creiamo l’interfaccia generica IRepository<T, idT> nel progetto di DataAccess e l’interfaccia specifica IUserRepository e la classe concreta che andremo (in seguito) ad implementare per interrogare il Database all’interno del progetto contenente le entità.

   1: namespace DataAccess
   2: {
   3:     public interface IRepository<T, idT>
   4:     {
   5:         T GetById(idT id);
   6:         idT Add(T entity);
   7:         void Delete(T entity);
   8:     }
   9: }
   1: namespace Domain.Repositories
   2: {
   3:     public interface IUserRepository : IRepository<User, int>
   4:     {
   5:     }
   6:  
   7:     public class UserRepository : IUserRepository
   8:     {
   9:         private ISession session;
  10:         
  11:         public UserRepository(ISession session)
  12:         {
  13:             this.session = session;
  14:         }
  15:  
  16:         public User GetById(int id)
  17:         {
  18:             throw new System.NotImplementedException();
  19:         }
  20:  
  21:         public int Add(User entity)
  22:         {
  23:             throw new System.NotImplementedException();
  24:         }
  25:  
  26:         public void Delete(User id)
  27:         {
  28:             throw new System.NotImplementedException();
  29:         }
  30:     }
  31: }

Le ultime cose che mancano sono:

  1. Un file di configurazione per dire a NH che driver utilizzare per l’accesso ai dati e alcune informazioni di configurazione: Anche per questo tipo di configurazione ci affideremo a fluent.NHibernate che mette a disposizione una fluent per configurare NH senza troppe linee di codice
  2. Il mapping dell’entità creata con l’entità logica sul database.

Configurazione Database:

   1: var cfg = new SQLiteConfiguration().InMemory().ShowSql();
   2: PersistenceModel model = new PersistenceModel();
   3: model.addMappingsFromAssembly(Assembly.GetAssembly(typeof(User)));
   4: sessionSource = new SessionSource(cfg.ToProperties(), model);

E il mapping dichiarativo utilizzando flluent-Nhibernate:

   1: public class UserMap : ClassMap<User>
   2: {
   3:     public UserMap()
   4:     {
   5:         WithTable("Users");
   6:         Id(x => x.Id);
   7:         Map(x => x.Name);
   8:         Map(x => x.SurName);
   9:     }
  10: }

La classe di mapping è abbastanza semplice, bisogna estendere la classe ClassMap<T> dove T è l’entità che stiamo mappando e nel costruttore, grazie all’uso di un bel po’  di Lambda e fluent interfaces, desciviamo il mapping, dicendogli che:

  1. La tabella su cui viene mappata l’entità è la tabella “users”
  2. La property Id della nostra entità rappresenta la chiave primaria della tabella (per convenzione, se non specifico nulla, il nome dell’entità e il nome della colonna sono gli stessi) salvata in una colonna “Id”.
  3. Le property Name e Surname sono mappate rispettivamente sulle colonne “Name” e “SurName” della tabella.

Faccio qui contento un mio amico / collega (roberto valenti) e procedo con scrivere un po’ di test per controllare che tutto sia predisposto correttamente.

Abbiamo quindi una prima configurazione del nostro layer di persistenza, sa dove dover andare a persistere i nostri dati grazie al file xml, sa che tipi di dati andrò a persistere (le nostre entità) e sa anche, tramite il nostro mapping, come persistere questi dati sul datasource. Vediamo di testare subito se tutto il lavoro di configurazione funziona. In fase di Setup del test, costruiamo un Configuration, che ci servirà per recuperare la ISession per interrogare i dati sulla sorgente dati. Verifichiamo che con la configurazione data, è possibile generare lo schema del database conoscendo i mapping, e se successivamente verifichiamo di essere in grado ad effettuare un inserimeno di uno User e successivamente recuperarlo sempre tramite la session.L’unico test che abbiamo implementato è quello di smoke, trovato girovagando per i blog mi sembrava un buon metodo per controllare che la configurazione sia andata senza nessun problema e lo schema sia stato generato correttamente.

   1: [TestFixture]
   2: public class MappingFixtures
   3: {
   4:     private Configuration config;
   5:  
   6:     [SetUp]
   7:     public void Context()
   8:     {
   9:         var cfg = new SQLiteConfiguration()
  10:             .ShowSql()
  11:             .ConnectionString.Is( "Data Source=nhibernate.db;Version=3");
  12:         PersistenceModel model = new PersistenceModel();
  13:         model.addMappingsFromAssembly(Assembly.GetAssembly(typeof(User)));
  14:         config = cfg.ConfigureProperties(new Configuration());
  15:         model.Configure(config);
  16:         SchemaExport export = new SchemaExport(config);
  17:         export.Execute(false, true, false, false);
  18:     }
  19:  
  20:     [Test]
  21:     public void smoke()
  22:     {
  23:         // pass if config is OK and schema have been created
  24:         Assert.IsTrue(true);
  25:     }
  26: }

Scriviamo ora i test per il salvataggio dell’entità.

   1: [Test]
   2: public void UserShouldBeAddedToDb()
   3: {
   4:     User u = new User();
   5:     u.Name = "Gianluca";
   6:     u.SurName = "Gravina";
   7:     ISessionFactory factory = config.BuildSessionFactory();
   8:     ISession session = factory.OpenSession();
   9:     IUserRepository repo = new UserRepository(session);
  10:     int x = repo.Add(u);
  11:     Assert.IsTrue(x != 0);
  12: }

Come da Red Green, il test non passerà, andiamo quindi a scrivere il metodo per fare passare il test.

   1: public int Add(User entity)
   2: {
   3:     return (int)session.Save(entity);
   4: }

Facciamo la stessa cosa con la GetById e con la Delete, scriviamo i test, ma prima aggiungiamo una GetAll ai repository in modo da recuperare tutte le entità di un certo tipo:

   1: public IList<User> GetAll()
   2: {
   3:     return session.CreateCriteria(typeof (User)).List<User>();
   4: }
ed ecco i test:
   1: [Test]
   2: public void CanRetrieveUsersFromDataBase()
   3: {
   4:     ISession session = config.BuildSessionFactory().OpenSession();
   5:     UserRepository repo = new UserRepository(session);
   6:     User u = repo.GetById(1);
   7:     Assert.IsNotNull(u);
   8:     Debug.WriteLine(u.Name + " " + u.SurName);
   9: }
  10:  
  11: [Test]
  12: public void CanDeleteUsersFromDataBase()
  13: {
  14:     ISession session = config.BuildSessionFactory().OpenSession();
  15:     UserRepository repo = new UserRepository(session);
  16:     int x = repo.GetAll().Count;
  17:     User u = repo.GetById(1);
  18:     repo.Delete(u);
  19:     session.Flush();
  20:     int y = repo.GetAll().Count;
  21:     Assert.IsTrue(x-y==1);
  22: }

e le relative implementazioni:

   1: public User GetById(int id)
   2: {
   3:     return session.Load<User>(id);
   4: }
   5:  
   6: public void Delete(User entity)
   7: {
   8:     session.Delete(entity);
   9: }

e con questo abbiamo (più o meno) finito.

Abbiamo configurato mapping e datasource con FluentInterface di Nhibernate, abbiamo creato le classi Repository per l’interrogazione del datasource e abbiamo testato che tutto funziona.

References:

Technorati Tags: ,

author: Gianluca Gravina | posted @ giovedì 15 gennaio 2009 17:18 | Feedback (0)

Fluent NHibernate


Recentemente mi sono imbattuto in questa fantastica libreria per NHibernate. Tra le varie funzionlità quelle di AutoMapping:James Gregory ha scritto un conciso tutorial per cominciare ad usarle.

Commenti: da approfondire l’uso e  le funzionalità proproste, ma di primo acchito direi eccezionale !

author: Gianluca Gravina | posted @ domenica 11 gennaio 2009 20:29 | Feedback (0)

Windows Live Writer


Dopo aver letto “dal twitter di Simone”, che l’ultima versione di WL non dava problemi con W2008 … ho scaricato e ho provato a installare …

Bhé, non è stato proprio indolore, se qualcuno dovesse avere problemi, soprattutto in presenza di precedenti versioni beta, vi consigli ZapMessenger.

HTH

author: Gianluca Gravina | posted @ martedì 16 dicembre 2008 16:14 | Feedback (0)

ASP.NET Mvc beta


Avevo letto qualcosa in merito ma non l’avevo collegata a questo problema.

E’ da un paio di giorni che apro il mio fidato VS2008 e spesso (troppo spesso) e volentieri (purtroppo) crashava senza motivo … guardo sull’eventlog e trovo una serie di errori di questo tipo:

.NET Runtime version 2.0.50727.3053 - Fatal Execution Engine Error (58450F92)

Googlando in giro trovo la causa: “Power Commands” di visual studio e ASP.NET Mvc beta installati contemporaneamente …

Quale disinstallo ??? Simone non me ne vorrà, ma visto che al momento non sto sviluppando nulla con MVC, I power commands sono ancora presenti e pronti all’uso … e il problema sembra effettivamente scomparso !

author: Gianluca Gravina | posted @ mercoledì 26 novembre 2008 16:05 | Feedback (1)

Visual studio next AND .Net Framework 4


PDC, tante novità … e tra tutte:

Visual studio & NET framework 4

author: Gianluca Gravina | posted @ lunedì 27 ottobre 2008 22:05 | Feedback (0)

Google Chrome


Sarò onesto, ho letto di sfuggita l'articolo sui principali quotidiani online ... ma non pensavo fosse quasi pronto da scaricare ...

Pronti via ... spettacolo !!!!!!!!

image

Prima ottima impressione: IMMEDIATO

Seconda ottima impressione, clic con il tasto destro ... ispeziona elemento ... ed eccolo, un piccolo emulo di Firebug che compare a farci vedere un po' di informazioni dettagliate sul DOM.

Come promesso, non esiste più un solo processo .... ma un processo per ogni Tab di chrome (di recente ho portato avanti una "crociata" per la reintroduzione delle chiamate sincrone per SL, eliminate proprio per evitare di "lockare" il processo di Explorer, o firefox, e ci siamo dovuti inventare un metodo tutto nostro per simulare) e diciamo che questo potrebbe eliminare tale problema ridando un po' di sincronismo che onestamente in alcuni momenti mi manca ...

Adesso aspetto:

1) Plugins vari (senza AdBlock non mi muovo dal mio firefox)

2) Migliori performance (in quanto a Ram i vari processi se ne prendono abbastanza, magari facendo le somme è la stessa quantità di FF ma non ho ancora fatto un controllo accurato).

3) i temi (giusto per fare il pignolo)

4) Silverlight

5) ... basta così, per il resto sembra fatto molto bene !

 

Technorati Tag:

author: Gianluca Gravina | posted @ martedì 2 settembre 2008 23:57 | Feedback (0)