The official Fatica Labs Blog! RSS 2.0
# Tuesday, April 27, 2010

stringtemplate Una libreria che ho utilizzato più volte, ma che è secondo me misconosciuta è ANTLR StringTemplate. E’ parte di un progetto molto più grande ed importante, ovvero il generatore di linguaggi ANTLR, ma qui ci interessa la libreria di templating.

bene: che cosa è ? E’ un template engine, ovvero un componente che, data qualche forma di metadata mi produce un documento di testo il cui contenuto è in qualche modo pilotato dal metadata. Semplice? Forse un esempio è meglio:

Supponiamo di avere un oggetto .NET rappresentante una carrello della spesa di un sito web. Questo rappresenta il nostro metadata. Ora supponiamo che vogliamo scrivere una mail riassuntiva, rappresentante il contenuto del carrello. Ovviamente dovrebbe essere facile modifcare il corpo di questa mail, la sua formattazione, tramite una semplice configurazione. Vediamo come potrebbe essere l’oggetto carrello in questione:

   1: public class Basket
   2: {
   3:     public Basket ()
   4:     {
   5:         BasketItems = new List<BasketItem>();
   6:     }
   7:     public string UserName { get; set; }
   8:     public string UserSurname { get; set; }
   9:     public string UserEmail { get; set; }
  10:     public IList<BasketItem> BasketItems { get; set; }
  11: }
  12:  
  13: public class BasketItem
  14: {
  15:     public string Code { get; set; }
  16:     public string Description { get; set; }
  17:     public int Count { get; set; }
  18:     public decimal UnitPrice { get; set; }
  19:     public decimal Price { get { return UnitPrice * Count; } }
  20: }

Bene, ora scriviamo il template della mail, nel linguaggio di StringTemplate:

   1: Dear Mr $Basket.UserName$,$Basket.UserSurname$
   2:  
   3: Your order contains:
   4:  
   5: Item #    Description        Qty    Unit Cost    Total Cost
   6: $Basket.BasketItems:
   7: {
   8: $it.Code$    $it.Description$        $it.Count$    $it.UnitPrice$        $it.Price$ }
   9: $
  10:  
  11: ______________________________
  12: Thanks for ordering @ ACME.ORG

Da notare, se siete abituati ad altri template engine ( ASP è uno di questi, ma anche T4 ) noterete che questi quando lavorano con collezioni vi fanno scrivere qualcosa come <% for….. %>, facendovi fare il template in modo procedurale. StringTemplate usa invece un approccio dichiarativo $collection: {}$ tra le graffe va il template da ripeter per ogni item della collection. l’elemento corrente è rappresentato da $it$.

Ora bisogna procurere i binari del porting c# di StringTemplate. Mettete come reference nel vostro progetto le dll StringTemplate, ma ricordatevi che per il deploy servono tutte e tre le dll! Fatto questo, per processare il template basta scrivere:

   1: public void TryTemplate()
   2: {
   3:     using( var st =  new StreamReader("mailtemplate.txt") )
   4:     {
   5:         StringTemplate processor = new StringTemplate(st.ReadToEnd());
   6:         //GetBasket ritorna un basket di esempio
   7:         processor.SetAttribute("Basket", GetBasket());
   8:         //ToString processa il template con i dati...
   9:         Console.WriteLine(processor.ToString()); 
  10:     }
  11: }

Per ottenere l’output seguente:

   1: Dear Mr Will,Coyote
   2:  
   3: Your order contains:
   4:  
   5: Item #    Description        Qty    Unit Cost    Total Cost
   6:  
   7: 1    T.N.T Stick        200    0,45        90,00 
   8: 2    Chain Gun        1    1450        1450 
   9: 3    Rockets        60    200        12000 
  10:  
  11: ______________________________
  12: Thanks for ordering @ ACME.ORG

Semplice, e molto efficace. Questo è un esempio base, collection e parametri a me sono sempre bastati, ma la libreria in se è molto più potente: basta leggersi la documentazione. So benissimo che a qualcuno potrebbe venire voglia, di fronte ad una simile problematica, di scriversi una propria versione, ma… okkio, questa è una delle classiche cose semplici che vi portano via, a farla male, una giornata, ma a farla bene… beh, prendete quella già fatta perchè:

  • è collaudata - è usata come back-end di ANTLR, un genaratore di compilatori di successo-
  • è potente – gestisce collection, sostituzioni, inclusioni, join etc etc
  • è open source, ed è in C#.
Tuesday, April 27, 2010 10:31:08 PM (GMT Daylight Time, UTC+01:00)  #    Comments [3] - Trackback
Programmin

Per abilitare il logging delle query con NHibernate occorre:

  1. Avere nella bin dell applicativo ( ie: nella /bin per le applicazioni web, a fianco dell’ esequibile per le applicazioni stand-alone ) la dll di log4net.
  2. Aggiungere nel file di configurazione la sessione di config per log4net:
  3. <configuration>
      <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>

      </configSections>
      <log4net>
        <appender name="console" type="log4net.Appender.ConsoleAppender">
          <layout type="log4net.Layout.PatternLayout">
            <param name="ConversionPattern" value="%-5p - %m%n" />
          </layout>
        </appender>
        <logger name="NHibernate.SQL" additivity="false">
          <level value="ALL"/>
          <appender-ref ref="console" />
        </logger>
        <root>
          <priority value="WARN" />
          <appender-ref ref="console" />
        </root>
      </log4net>
    </configuration>

    Con questa configurazione si usa il console appender, per un’applicativo web potrebbe essere meglio usare un TraceAppender o un altro appender di proprio gusto ;-)

     

  4. Assicurarsi di chiamare, almeno una voltanell’applicazione log4net.XmlConfigurator.Configure()
  5. Aggiungere questa proprietà nella configurazione di NH:                                         <property name="show_sql">true</property>

Se NON vogliamo mettere nulla di log4net nella configurazione:

Possiamo configurare log4net dall’ applicativo, con un paio di linee di codice:

   1:              TraceAppender app = new TraceAppender();
   2:              app.Layout = new SimpleLayout();
   3:              LoggerMatchFilter filter = new LoggerMatchFilter();
   4:              filter.LoggerToMatch="NHibernate.SQL";
   5:              filter.AcceptOnMatch = true;
   6:              filter.ActivateOptions();
   7:              app.AddFilter(filter); // L'ordine di questo filtro
   8:              app.AddFilter(new DenyAllFilter()); // e di quest'altro E' importante
   9:              app.ActivateOptions();
  10:              BasicConfigurator.Configure( app);
 
 
 

In questo caso si possono saltare gli step da 1 a 3. Questo codice deve essere chiamato una volta nell’applicazione in fase di startup, per un’applicazione web, potrebbe andare bene l’evento di startup dell'applicazione in global.asax. Con l’appender e i filtri configurati si ottiene nell'area trace di Visual Studio ( Output-tab Debug)  l’output delle sole query generate da NH ( senza gli altri logger, se servono  si possono togliere i filtri )

Tuesday, April 27, 2010 4:43:20 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0] - Trackback
NHibernate | log4net

# Sunday, April 25, 2010

Mauricio Scheffer has just released a web based console for editing HQL. He based the intellisense on my project. I’m happy to see some of my effort reused somewhere! So thanks to Mauricio.

Sunday, April 25, 2010 10:29:44 AM (GMT Daylight Time, UTC+01:00)  #    Comments [0] - Trackback
HQL Intellisense | NHibernate

# Thursday, April 22, 2010

There is some interesting progress with my project Fatica.Labs.HqlEditor. I just want to share some screenshot:

s5

Well, it is growing to be a real tool, and in my idea would became a sort of test bed in which the user can add or modify mapping, try the queries, change the config, export a database script, reverse engineering and so on. Actually all the low level tool to achieve that are available.

Ok, let’s explain the layout:

  1. The document area, here we have mapping/config/hql all with intellisense. In the screenshot the code completion for an Hql is shown. In future maybe I will be able to insert a T4 editor for the hbm2net templates.
  2. The project area: here we have a bounch of file that are representing our testing project: mapping, configurations, assemblies and so on. I have use the MSbuild object as a backend for the project, because in the near future I would like to use it to really build some artifacts using hbm2net and db2hbm.
  3. Here is the SQL preview of the query in editing. Now the view is showing an error because the query is incomplete.
  4. The funny log, a graphical appender for log4net :-)

Some more words about the project itself: the testing environment is hosted in a separate appdomain, this will allow us to:

  • Modify the mapping runtime generating new version of the assembly
  • Testing production assemblies built with legacy nh versions ( well, not so legacy, starting from 2.xxx )

Let’s have another screenshot, showing a real SQL preview:

s7

Next step is to produce the query results in some sort of usable representation ( I need to push the data across two app domain ) so I would probably use some JSON serialization and then display the JSON raw data with some readable formatting.

You can see a little demo video here.

The project is not yet released, please treat it as a CTP ;) anyway, the svn repository is here:

https://faticalabshqled.svn.sourceforge.net/svnroot/faticalabshqled

Thursday, April 22, 2010 5:41:58 PM (GMT Daylight Time, UTC+01:00)  #    Comments [2] - Trackback
Code GEneration | HQL Intellisense | NHibernate | NHWorkBench

# Wednesday, April 21, 2010

E’ da un po’ che in una certa realtà lo ripeto, ma non avevo mai trovato qualcosa di ufficiale a conforto. Adesso l’ho trovato.

In pratica vediamo perchè, scrivere l’interfaccia ICustomer sull’entità Customer sia sempre un errore. Sempre. Non in qualche caso. Perchè un entità non ha comportamenti. Un entità, per esempio “Customer” ritorna sempre la stessa cosa quando le si chiede, ad esempio, Name. Non c’è un algoritmo od una strategy che possa abbellire o rendere più intelligente il comportamento di Name. E’ poi interessante vedere come larchitettura diventa semplicemente oscena quando ICustomer ha per esempio un IAddress o qualsiasi altra reference…

Poichè è anche considerato un antipattern il Domain Model anemico ( cioè quello composto da sole entità  senza comportamenti) chi si ferma a leggere le prime righe di tutti gli articoli potrebbe pensare che piazzare su una bella interfaccia per ogni entità sia la soluzione. Questo non è però vero: vanno messi “dietro ad un interfaccia” i comportamenti che ha senso pensare che possano variare, ed eventualmente le entità potranno implementare una o più di queste interfacce di behavior. Per esempio Customer potrebbe implementare ICanPlaceHorder, e la logica con cui si piazza l’ordine potrebbe cambiare, ma le entità in gioco sono concrete.

Un interessante find storico sulla situazione è un caso pratico di Prima & Dopo.

Wednesday, April 21, 2010 1:13:42 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0] - Trackback
Programmin

# Tuesday, April 20, 2010

Fabio Maulo sta proponendo una nuova astrategia di mapping per NHibernate: ConfORM. In pratica si tratta di una strategia code only, quindi nessun file di XML, ma tutto via codice con l’approccio fluent interface. Stranamente la community si è un po’ stupita di vedere un ennesima strategia, e tutti stanno lì a chiedersi il perchè. Bene, il perchè è che è una nuova possibilità di scelta, ed avere molte scelte è un plus degli ambienti open source. In un suo post Fabio disegna uno scenario completo della ricca rosa di partecipanti al problema mapping. Difatto ConfORM è l’unica API che sfonda completamente lo strato hbm, e va direttamente alla radice. Tutto questo si traduce immediatamente in un incremento di performance, ed in una migliore linearità progettuale: meno strati è meglio, anzi, meno strati inutili è meglio. Francamente, dopo una piccola esperienza acquisita nel problema mapping con la scrittura del tool NHModeller, ho deciso di tornare ed imparare la strategia HBM. Dopo un po’ non è così male, ma la prossima volta che faccio un progetto mio provo ad usarlo ( in azienda non se ne parla nemmeno: già il mapping XML è visto come una stregoneria, e c’è chi legifera che mappare le foreign Key come long sia una buona idea anzichè un antipattern ;-) ).

In conclusione: chissenefrega se un nuovo sistema sembra essere il duplicato di un altro:Vincerà il migliore, ed in ogni caso il migliore secondo gli utilizzatori :-)

Tuesday, April 20, 2010 7:22:46 PM (GMT Daylight Time, UTC+01:00)  #    Comments [6] - Trackback
ConfORM | NHibernate

My Stack Overflow
Contacts

Send mail to the author(s) E-mail

Tags
profile for Felice Pollano at Stack Overflow, Q&A for professional and enthusiast programmers
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2012
Felice Pollano
Sign In
Statistics
Total Posts: 143
This Year: 3
This Month: 0
This Week: 0
Comments: 105
This blog visits
All Content © 2012, Felice Pollano
DasBlog theme 'Business' created by Christoph De Baene (delarou) and modified by Felice Pollano