[OT] 100 Pushups challenge

Accettare la sfida è stato facile smile_teeth...però ora arriva la parte difficile, raggiungere l'obbiettivo!! smile_confused 

La prima fase è un test iniziale nel quale ho fatto 25 flessioni di fila!! ( + 1 infarto smile_wink)

Technorati Tag: ,

Usare RhinoMocks per testare applicazioni multithreading

Interessato dal post di Antonio sull'uso del TDD per progettare applicazi multithreading ho deciso di riprovare senguendo il percorso logico da lui espresso, usando RhinoMocks come framework di mocking piuttosto che i mocks manuali usati da Antonio per non complicare il codice di test. La versione di RhinoMocks utilizzata è la 3.5 RC che potete scaricare a questo url, questa versione della libreria supporta la sintassi Arrange/Act/Assert permettendo di scrivere test molto più chiari, per maggiori info visitate questa pagina.

Adesso vediamo e commentiamo i vari metodi di test, cominciamo con il primo:

   1:  public void When_Enqueue_A_Log_The_LogWriter_Is_Invoked()
   2:  {
   3:      var log = new Log();
   4:      var writer = MockRepository.GenerateMock<ILogWriter>();
   5:      var thread = new LogThread(writer);
   6:   
   7:      thread.Enqueue(log);
   8:   
   9:      writer.AssertWasCalled(x => x.Write((Arg<Log>.Is.Equal(log))));
  10:  }

Le differenze sostaziali sono, alla riga 4 e 9, nella prima generiamo un mock dell'interfaccia ILogWriter e nella seconda "chiediamo" al mock object di verificare se è stato chiamato il metodo Write e se il parametro in ingresso era uguale a log. Proseguiamo con il secondo test:

   1:  public void The_Calls_To_The_Writer_Are_Asynchronous()
   2:  {
   3:      var log = new Log();
   4:      var writer = MockRepository.GenerateMock<ILogWriter>();
   5:      var thread = new LogThread(writer);
   6:      int writerCallCount = 0;
   7:      var resetEvent = new ManualResetEvent(false);
   8:   
   9:      writer.Expect(x => x.Write((Arg<Log>.Is.Anything))).Do(new Action<Log>(l =>
  10:      {
  11:          writerCallCount++;
  12:          resetEvent.WaitOne();
  13:          writerCallCount--;
  14:      }));
  15:   
  16:      thread.Enqueue(log);
  17:      while (writerCallCount == 0)
  18:      {
  19:          Thread.Sleep(0);
  20:      }
  21:      Assert.AreEqual(1, writerCallCount);            
  22:      resetEvent.Set();
  23:  }

La parte interessante in questo test sono le righe dalla numero 9 alla 14, dove istruisco il mock object. In pratica non faccio altro che "dire" al mock object "quando viene invocato il metodo Write con una qualsiasi istanza di Log, esegui la seguente Action". Il delegate passato come Action al metodo Do esegue la solita logica del mock manuale usato da Antonio. Per il resto il codice di test è sostanzialmente identico. La logica del terzo metodo di test è la solita quindi vi posto solo il codice:

   1:  public void Two_Logs_Enqueued_Are_Served_One_At_Time()
   2:  {
   3:      var writer = MockRepository.GenerateMock<ILogWriter>();
   4:      var thread = new LogThread(writer);
   5:      int writerCallCount = 0;
   6:      var resetEvent = new ManualResetEvent(false);
   7:   
   8:      writer.Expect(x => x.Write((Arg<Log>.Is.Anything))).Do(new Action<Log>(l =>
   9:      {
  10:          writerCallCount++;
  11:          resetEvent.WaitOne();
  12:          writerCallCount--;
  13:      }));
  14:   
  15:      Log log1 = new Log();
  16:      thread.Enqueue(log1);
  17:      while (writerCallCount < 1)
  18:      {
  19:          Thread.Sleep(0);
  20:      }
  21:   
  22:      Log log2 = new Log();
  23:      thread.Enqueue(log2);
  24:      while (thread.RunningThreadCount < 2)
  25:      {
  26:          Thread.Sleep(0);
  27:      }
  28:   
  29:      Assert.AreEqual(1, writerCallCount);
  30:   
  31:      resetEvent.Set();
  32:      while (writerCallCount > 0)
  33:      {
  34:          Thread.Sleep(0);
  35:      }
  36:  }

In fine passiamo all'ultimo metodo di test:

   1:  public void When_The_Writer_Throws_An_Exception_The_QueueLength_Is_Decreased()
   2:  {
   3:      var writer = MockRepository.GenerateMock<ILogWriter>();
   4:      var thread = new LogThread(writer);
   5:      bool isWriting = false;
   6:   
   7:      writer.Expect(x => x.Write((Arg<Log>.Is.Anything))).Do(new Action<Log>(l =>
   8:      {
   9:          isWriting = true;
  10:          throw new Exception();
  11:      }));
  12:   
  13:      thread.Enqueue(new Log());
  14:      while (!isWriting)
  15:      {
  16:          Thread.Sleep(0);
  17:      }
  18:      while (thread.RunningThreadCount > 0)
  19:      {
  20:          Thread.Sleep(0);
  21:      }
  22:      Assert.AreEqual(0, thread.RunningThreadCount);
  23:  }

Anche qui la parte interessante è la configurazione del mock object, in questo test la sintassi del mock rimane uguale ai test precedenti, quello che cambia è la logica contenute nell' Action delegate passato al metodo Do, il quale scatena un' eccezione.

Nel mio repository personale ho creato tre proggeti uno con la versione manuale dei mocks, uno che usa RhinoMocks ed in fine uno che usa Moq, il tutto è reperibile a questo url: http://makesimple.googlecode.com/svn/trunk/UnitTestMultithreading

Mixin, POCO e INotifyPropertyChanged mito o realtà?

Dopo aver chiesto ad i CDays2008 a Mauro cosa pensava dei mixin, dopo aver letto i vari post di Andrea, Raffaele e Gian Maria che parlano di POCO e dopo aver letto i due post (qui e qui) nel blog inglese di Gian Maria ho deciso di spiegare meglio cosa intendevo con il mio commento al post di Andrea.

Gian Maria mostra due modi diversi per rivolvere il "problema" dell'interfaccia INotifyPropertyChanged creando proxy a run-time, io avevo risolto il solito problema usando Spring.NET AOP. Questo dimostra che come al solito ci sono svariati modi per ottenere il solito risultato.

Finita questa piccola anticipazione arrivo al nocciolo del discorso e sparo la mia sentenza...nessuna di queste implementazioni è usabile!! Vi chiederete perchè ed io sono qui per dimostrarvelo. Piccola demo, provate a creare una semplice BindingList<Customer>, aggiungete ad essa un numero imprecisato di Customer-proxaty, agganciate l'evento ListChanged ed in fine provate a modificare la proprietà di un Customer della BindingList...et vualà l'evento non viene scatenato, cosa che dovrebbe accadere se Customer implementasse normalmente INotifyPropertyChanged.

init

Quando per la prima volta mi sono trovato davanti a questo problema armato di Reflector sono andato a sbirciare il codice della classe BindingList<T> ed ho trovato l'inghippo. Guardando il codice mostrato nell'immagine vediamo che la seconda linea di codice verifica se il tipo INotifyPropertyChanged è assegnabile dal tipo Customer, questa verifica nel caso di Customer in versione POCO è assolutamente falsa dato che il tipo Customer non sa niente di INotifyPropertyChanged. Per confermare questa teoria mi sono creato un po di test unitari che riproducono il problema, vediamoli. In entrambi i casi di test la creazione del Customer è stata "nascosta" dentro dei metodi Factory dato che non mi interessa mostrarne l'implementazione in questo post. Per prima cosa ho creato due classi Customer la prima implementa INotifyPropertyChanged e la seconda no, però ha le properties marcate come virtual per permettere la creazione del proxy a run-time. 

   1: public class Customer : INotifyPropertyChanged
   2: {
   3:     public event PropertyChangedEventHandler PropertyChanged;
   4:     private Guid id = Guid.NewGuid();
   5:     private string name;
   6:  
   7:     public Guid Id {
   8:         get { return id; }
   9:     }
  10:     public string Name {
  11:         get { return name; }
  12:         set {
  13:             if (name != value) {
  14:                 name = value;
  15:                 RaisePropertyChanged("Name");}
  16:             }
  17:     }
  18:     private void RaisePropertyChanged(string propertyName)
  19:     {
  20:         if (PropertyChanged != null)
  21:             PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  22:     }
  23: }
   1: public class CustomerPoco
   2: {
   3:     private Guid id = Guid.NewGuid();
   4:  
   5:     public virtual Guid Id {
   6:         get { return id; }
   7:     }
   8:     public virtual string Name { get; set; }
   9: }

Dopodiché ho creato due metodi di test, uno verifica se il Customer è castabile a INotifyPropertyChanged mentre l'altro verifica se è assegnabile.

   1: [Fact]
   2: public void ShouldBeCompatibleWithTypeINotifyPropertyChanged()
   3: {
   4:     Customer customer = CustomerFactory.CreateCustomer();
   5:     (customer is INotifyPropertyChanged).ShouldBeTrue("Is not INotifyPropertyChanged");
   6: }
   7: [Fact]
   8: public void ShouldBeAssignableToTypeINotifyPropertyChanged()
   9: {
  10:     typeof(INotifyPropertyChanged).IsAssignableFrom(typeof(Customer))
  11:         .ShouldBeTrue("INotifyPropertyChanged is not assignable from Customer");
  12: }

In questo caso entrabi i test passano perfettamente, proseguiamo eseguendo i soliti test su CustomerPoco:

   1: [Fact]
   2: public void ShouldBeCompatibleWithTypeINotifyPropertyChanged()
   3: {
   4:     CustomerPoco customer = CustomerFactory.CreateCustomerPoco();
   5:     (customer is INotifyPropertyChanged).ShouldBeTrue("Is not INotifyPropertyChanged");
   6: }
   7: [Fact]
   8: public void ShouldBeAssignableToTypeINotifyPropertyChanged()
   9: {
  10:     typeof(INotifyPropertyChanged).IsAssignableFrom(typeof(CustomerPoco))
  11:         .ShouldBeTrue("INotifyPropertyChanged is not assignable from CustomerPoco");
  12: }

In quest'ultimo caso il primo test passa mentre il secondo no distruggendo i nostri sogni di sviluppatore lazy che non doveva più implementare INotifyPropertyChanged smile_wink. Ecco perchè nel mio commento al post di Andrea ho detto: "...perchè il framework di per se non conosce i mixin quindi è stato scritto "bloccandone" l'uso". Problemi simili sono risolvibili con diversi hack, basta barare con un po di reflection dopo aver istanziato la collection:

   1: private static void EditRaiseItemChangedEvents(BindingList<Customer> list)
   2: {
   3:     FieldInfo _fi = list.GetType().GetField("raiseItemChangedEvents", BindingFlags.NonPublic | BindingFlags.Instance);
   4:     bool raiseItemChangedEvents = (bool)_fi.GetValue(list);
   5:     if (!raiseItemChangedEvents) _fi.SetValue(list, true);
   6: }

ed il gioco è fatto ma in generale hanno un costo troppo alto, sia di implementazione che di manutenzione dato che il problema non si presenta solo per collection come la BindingList ma anche per controlli come il BindingSource delle WindowsForm.

Google C++ Testing Framework

Nei miei projetti C# faccio un largo uso di test unitari, utilizzando NUnit o xUnit.NET, so già che entro la fine dell'anno prenderò in consegna una grande applicazione C++, quindi in passato avevo dato un'occhiata veloce a quello che era il framework di  testing di riferimento: CppUnit .
Adesso Google ha rilasciato il proprio framework per fare testing automatico di codice C++, non l'ho ancora provato (...aaahhhh il tempo) ma sembra proprio ottimo!

Fonte: InfoQ: Announcing: New Google C++ Testing Framework

Extension Methods and Instace Methods Conflicts

Leggendo il libro LINQ in Action vinto ai Community Days 2008 (consegnato direttamente da Andrea) ho scoperto un comportamento degli Extension Methods che non conoscevo. Il quesito posto nel libro è: cosa succede se un Extension Method va in conflitto con un Instace Method? Semplicemente "perde la battaglia" in quanto un Extension Method ha una priorità più bassa. Riporto lo snippet e l'output presenti nel libro:

   1: using System;
   2:  
   3: namespace ExtensionMethods
   4: {
   5:     class Class1
   6:     {
   7:     }
   8:     class Class2
   9:     {
  10:         public void Method1(string s)
  11:         {
  12:             Console.WriteLine("Class2.Method1");
  13:         }
  14:     }
  15:     class Class3
  16:     {
  17:         public void Method1(object o)
  18:         {
  19:             Console.WriteLine("Class3.Method1");
  20:         }
  21:     }
  22:     class Class4
  23:     {
  24:         public void Method1(int i)
  25:         {
  26:             Console.WriteLine("Class4.Method1");
  27:         }
  28:     }
  29:     static class Extension
  30:     {
  31:         static public void Method1(this object o, int i)
  32:         {
  33:             Console.WriteLine("Extension.Method1");
  34:         }
  35:     }
  36:     class Program
  37:     {
  38:         static void Main(string[] args)
  39:         {
  40:             new Class1().Method1(12);
  41:             new Class2().Method1(12);
  42:             new Class3().Method1(12);
  43:             new Class4().Method1(12);
  44:         }
  45:     }
  46: }
   1: Extension.Method1
   2: Extension.Method1
   3: Class3.Method1
   4: Class4.Method1

Come dimostrato dallo snippet un Extension Method viene chiamato solo quando non esiste un Instace Method con la solita firma. In VB.NET per default non abbiamo il solito comportamento in quanto il compilatore se necessario effettua una conersione automatica dei tipi, quindi l'output sarà:

   1: Extension.Method1
   2: Class2.Method1
   3: Class3.Method1
   4: Class4.Method1

per evitare questo comportamento dobbiamo impostare Option Strict On, causando un errore di compilazione.

Technorati Tag: ,,

Object Oriented Design Principles e Refactoring

Nella sessione Realizzare applicazioni estendibili e configurabili di Mauro si è parlato prima di tutto dei principi di design che permettono di rendere una applicazione estendibile e come migliorare tale design grazie al refatoring. A sessione finita mi sono soffermato fuori dalla sala con Mauro a discutere di come queste pratiche siano fondamentali per non rendere la nostra applicazione un monolite e come il TDD può aiutare a disegnare il proprio software rispettando i principi di design. Quindi mi sono deciso a scrivere questo post per fornite un po di risorse utili sull'argomento. Naturalmente questa lista pretende solo di far venire l'acquolina in bocca al lettore e non di essere totalmente completa. Per finire ci tengo a ricordare a tutti che prima di farsi idee positive o negative su qualsiasi argomento bisogna mettere mano al codice e provare, provare, provare!!!

Object Oriented Design Principles

Webcast di Riccardo Golia della serie Aspire Architect (prima e seconda): Post (blog di Riccardo Golia), WebCast su MSDN, Slide (su Guisa), Codice di esempio (su Guisa) .

Articoli di Jeremy D. Miller : Patterns in Practice - The Open Closed Principle (su MSDN Magazine), Just some little things to help you CodeBetter, Orthogonal Code, Using the Chain of Responsibility Pattern, On Writing Maintainable Code, Be not afraid of the Visitor Pattern, the big, bad Composite Pattern, or their little friend Double Dispatch .

Articoli (in formato PDF) sul sito Object Mentor : Principles and Patterns, The Single Responsibility Principle, The Open Closed Principle, The Liskov Substitution Principle, The Interface Segregation Principle, The Dependency Inversion Principle .

Articoli sul sito OODesign.com : Design Principles

Articolo di Ayende (Oren Eini): Inversion of Control and Dependency Injection: Working with Windsor Container

Refactoring

Articoli e Screencasr di Jimmy Bogard : Separation of Concerns - how not to do it, Part 1, Part 2, Part 3, Part 4, PabloTV: Eliminating static dependencies screencast

Articoli su Wikipedia e WikiUGIdotNET: Code refactoring, Refactoring

Catalogo delle operazioni di refactorign: Refactorings in Alphabetical Order

Technorati Tag: ,,

Phun - the 2D physics sandbox

Sia che la fisica vi piaccia o no non potete non andare a guardare questo software sviluppato da uno studente di una Università Svedese. Veramente impressionante!

www.phun.at/

[WPF] Accedere alla UI da un thread secondario

Nicolò commentando il mio ultimo post mi ha chiesto di mostrare: "...un esempio in cui si accede da un thread secondario a quello che gestisce l'interfaccia utente?" niente di più facile! Per la (piccola) demo ho creato un'applicazione WPF, all'interno della Window ho inserito uno StackPanel con un TextBlock (da aggiornare) e due Button, il primo che mosta l'eccezione che viene scatenata se si prova ad accedere alla UI da un thread secondario ed il secondo che mostra come utilizzare la classe System.Windows.Threading.Dispatcher per accedere nella maniera corretta alla UI. Di seguito lo XAML:

<Window x:Class="AccessUIThreadDemo.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" SizeToContent="WidthAndHeight">
    <StackPanel>
        <TextBlock x:Name="textBlock1">Text</TextBlock>
        <Button x:Name="NotCorrect" Click="NotCorrect_Click">Update (Not Correct)</Button>
        <Button x:Name="Correct" Click="Correct_Click">Update (Correct)</Button>
    </StackPanel>
</Window>

ed il codice (C#) contenuto nel code-behind:

   1: public partial class Window1 : Window
   2: {
   3:     public Window1()
   4:     {
   5:         InitializeComponent();
   6:     }
   7:  
   8:     private void NotCorrect_Click(object sender, RoutedEventArgs e)
   9:     {
  10:         var t = new Thread(new ThreadStart(() => { textBlock1.Text = "Updated"; }));
  11:         t.Start();
  12:     }
  13:  
  14:     private void Correct_Click(object sender, RoutedEventArgs e)
  15:     {
  16:         var t = new Thread(new ThreadStart(() =>
  17:         {
  18:             this.Dispatcher.Invoke(DispatcherPriority.Normal, 
  19:                 new Action(() => { textBlock1.Text = "Updated"; }));
  20:         }));
  21:         t.Start();            
  22:     }
  23: }

come è facile vedere dallo snippet di codice, basta usare il metodo Invoke passando la priorità ed il delegate (metodo) da invocare. Tale metodo verrà inserito nella coda gestita dal Dispatcher della Window WPF.

DispatcherTimer, Yet Another Timer Class

Chiunque lavori da diverso tempo con il .NET Framework saprà che esistono diverse implementazioni della classeTimer, le quali sono:

Per maggiori informazioni leggete questo articolo di MSDN Magazine: http://msdn.microsoft.com/en-us/magazine/cc164015.aspx.

Con l'arrivo di WPF è stata introdotta un'altra classe Timer: System.Windows.Threading.DispatcherTimer.

Come ogni Timer che si rispetti la classe non fa altro che eseguire un operazione (metodo) allo scadere di un intervallo di tempo. Quindi la domanda che viene subito in mente è: perchè introdurre un'altra classe Timer?? Seplice, questa implementazione utilizza l'oggetto System.Windows.Threading.Dispatcher (anche questo introdotto nel .NET Framework con WPF) il quale permette di gestire una coda di operazioni (con priorità) per un singolo thread, molto utile quando dobbiamo accedere da un thread secondario a quello che gestisce l'interfaccia utente.

Come si può notare dal seguente snippet l'utilizzo di DispatcherTimer è molto semplice:

   1: DispatcherTimer timer = new DispatcherTimer();
   2: timer.Interval = TimeSpan.FromSeconds(5);
   3: timer.Tick += new EventHandler((sender, e) => { /* do something */ });
   4: timer.Start();

Usando il costruttore di default viene utilizzato il Dispatcher di default e la priorità Normal, per controllare queste due proprietà basta usare uno dei vari overlaod disponibili:

   1: ...
   2: public DispatcherTimer(DispatcherPriority priority);
   3: public DispatcherTimer(DispatcherPriority priority, Dispatcher dispatcher);
   4: ...

[OT] WRC - Rally d’Italia Sardegna 2008

Anche quest'anno, come quello passato, mi imbarcherò alla volta dell'edizione 2008 del Rally d'Italia Sardegna, tappa Italiana del Campionato Mondiale Rally. Partenza alle 21.00 di stasera e rientro alle 6.00 di Lunedì prossimo! La formula è...Giovedì Shakedown (prove libere) più parco assistenza per "strappare" qualche autografo...Venerdì, Sabato e Domenica accampato per le varie PS (Prove Speciali) in giro per la Gallura con la mia fedele tenda da battaglia alla ricerca di salti mozzafiato e traversi spettacolari!!

[Spring.NET #33] Spring.Aop, Advice

Rappresenta la modalità di intercettamento di un motodo e quindi la modalità di intruduzione del codice. I tipi di Advice sono quattro:

  • AroundAdvice: implementa l'interfaccia IMethodInterceptor e permette il massimo controllo su un metodo dato che possiamo aggiungere logica primo e dopo l'invocazione del metodo target. Questo è  l'Advice più potente ma anche il più richioso, dato che possiamo dimenticare di chiamare il metodo Proceed() che rappresenta l'invocazione del metodo target.
  • BeforAdvice: implementa l'interfaccia IBeforAdvice e permette di introdurre codice soltanto prima dell'invocazione del metodo target.
  • AfterReturningAdvice: impl