<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>.NET</title>
        <link>http://blogs.ugidotnet.org/dsantarelli/category/.NET.aspx</link>
        <description>.NET</description>
        <language>it-IT</language>
        <copyright>Dario Santarelli</copyright>
        <generator>Subtext Version 2.6.0.0</generator>
        <item>
            <title>Reactive Extensions (Rx) e Weak events</title>
            <link>http://blogs.ugidotnet.org/dsantarelli/archive/2012/03/25/reactive-extensions-rx-e-weak-events.aspx</link>
            <description>&lt;p&gt;Come molti sanno, il classico uso degli eventi in C# ha un effetto collaterale: se non viene gestita correttamente la strong reference che si forma tra l’oggetto che espone l’evento (&lt;em&gt;EventSource&lt;/em&gt;) e gli oggetti che registrano gli event handlers (&lt;em&gt;EventListeners&lt;/em&gt;), si rischia di generare dei &lt;a href="http://en.wikipedia.org/wiki/Memory_leak"&gt;memory leak&lt;/a&gt;. Infatti, se l’ &lt;em&gt;EventSource &lt;/em&gt;ha un ciclo di vita più lungo rispetto agli &lt;em&gt;EventListeners&lt;/em&gt;, questi ultimi, se non si deregistrano correttamente dall’evento, vengono tenuti in vita in memoria anche quando non ci sono più riferimenti attivi verso di essi e quindi non vengono reclamati dalla garbage collection fintantoché l’&lt;em&gt;EventSource&lt;/em&gt; è attivo.     &lt;br /&gt;
Nella letteratura esistono diverse tecniche per evitare questa tipologia di memory leak: &lt;a href="http://www.codeproject.com/Articles/29922/Weak-Events-in-C"&gt;questo articolo&lt;/a&gt; (“Weak Events in C#”) in particolare ne parla in maniera molto chiara e presenta vari approcci per implementare degli “weak event” (listener-side o source-side), ovvero degli eventi a cui un &lt;em&gt;EventListener&lt;/em&gt; può registrarsi senza incorrere nel rischio di diventare un memory leak. Le soluzioni ormai più diffuse sfruttano la classe &lt;a href="http://msdn.microsoft.com/en-us/library/system.weakreference.aspx"&gt;WeakReference&lt;/a&gt; , che permette di referenziare un oggetto in modo “&lt;a href="http://en.wikipedia.org/wiki/Weak_reference"&gt;debole&lt;/a&gt;”, ovvero mantenendolo comunque reclamabile dalla garbage collection.     &lt;br /&gt;
Giusto per citare un caso noto, WPF introduce un design pattern chiamato “&lt;a href="http://msdn.microsoft.com/en-us/library/aa970850.aspx"&gt;Weak Event&lt;/a&gt;”. Esso fondalmente si basa sull’implementazione concreta di un &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.weakeventmanager.aspx"&gt;WeakEventManager&lt;/a&gt;, ovvero un “dispatcher” centralizzato per ogni evento che vogliamo gestire in modalità weak (molti degli aspetti del data binding di WPF sono implementati tramite weak event). In questo pattern, poi, tutti i listener del weak event devono implementare l’interfaccia &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.iweakeventlistener.aspx"&gt;IWeakEventListener&lt;/a&gt; e quindi registrarsi/deregistrarsi all’evento passando per i metodi statici &lt;em&gt;AddListener()&lt;/em&gt; e &lt;em&gt;RemoveLister()&lt;/em&gt; che il &lt;em&gt;WeakEventManager&lt;/em&gt; mette a disposizione. Come si può intuire, questa soluzione introduce dell’infrastruttura che non sempre è semplice gestire, soprattutto in applicazioni esistenti che fanno un uso complesso e massivo di eventi.    &lt;br /&gt;
Pochi giorni fa ho provato quindi ad affrontare la questione attraverso il &lt;a href="http://msdn.microsoft.com/en-us/data/gg577609"&gt;Reactive Extensions (Rx) framework&lt;/a&gt; e devo dire che le soluzioni che si possono trovare sono alquanto iteressanti e flessibili. Vorrei mostrarne una in particolare.     &lt;br /&gt;
&lt;br /&gt;
Supponiamo di avere una classe &lt;em&gt;EventSource&lt;/em&gt; che espone un evento pubblico &lt;em&gt;Event&lt;/em&gt;.&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;EventSource &lt;br /&gt;&lt;/span&gt;{ &lt;br /&gt;    &lt;span style="color: blue;"&gt;public event &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;EventHandler &lt;/span&gt;Event;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: blue;"&gt;public void &lt;/span&gt;FireEvent()     &lt;br /&gt;    {         &lt;br /&gt;       &lt;span style="color: rgb(43, 145, 175);"&gt;EventHandler &lt;/span&gt;handler = Event;         &lt;br /&gt;       &lt;span style="color: blue;"&gt;if &lt;/span&gt;(handler != &lt;span style="color: blue;"&gt;null&lt;/span&gt;) handler(&lt;span style="color: blue;"&gt;this&lt;/span&gt;, &lt;span style="color: rgb(43, 145, 175);"&gt;EventArgs&lt;/span&gt;.Empty);     &lt;br /&gt;    }  &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: blue;"&gt;public int &lt;/span&gt;GetEventListenersCount()     &lt;br /&gt;    {         &lt;br /&gt;      &lt;span style="color: blue;"&gt;return &lt;/span&gt;Event.GetInvocationList().Count();     &lt;br /&gt;    } &lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Per fini di test esponiamo anche un metodo &lt;em&gt;FireEvent()&lt;/em&gt; che scatena l’evento ed un metodo &lt;em&gt;GetEventListenersCount() &lt;/em&gt;che ci restituisce il numero di listener correntemente registrati all’evento. Creiamo quindi uno &lt;em&gt;StrongEventListener&lt;/em&gt;, ovvero un listener che crea una strong reference all’&lt;em&gt;EventSource&lt;/em&gt; tramite la classica sintassi di registrazione ad un evento. Poichè questo oggetto non effettua esplicitamente la deregistrazione, diventa un potenziale memory leak.&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;StrongEventListener &lt;br /&gt;&lt;/span&gt;{             &lt;br /&gt;  &lt;span style="color: blue;"&gt;public &lt;/span&gt;StrongEventListener(&lt;span style="color: rgb(43, 145, 175);"&gt;EventSource &lt;/span&gt;eventSource)     &lt;br /&gt;  {        &lt;br /&gt;     eventSource.Event += HandleEvent;     &lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: blue;"&gt;private void &lt;/span&gt;HandleEvent(&lt;span style="color: blue;"&gt;object &lt;/span&gt;sender, &lt;span style="color: rgb(43, 145, 175);"&gt;EventArgs &lt;/span&gt;eventArgs)     &lt;br /&gt;  {        &lt;br /&gt;    &lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163, 21, 21);"&gt;"StrongEventListener&amp;gt; Event Received!"&lt;/span&gt;);     &lt;br /&gt;  } &lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;   &lt;br /&gt;
Per riuscire a implementare la corrispettiva versione weak (&lt;em&gt;WeakEventListener)&lt;/em&gt; in modo semplice e veloce è possibile sfruttare le &lt;a href="http://msdn.microsoft.com/en-us/data/gg577609"&gt;Reactive Extensions (Rx)&lt;/a&gt;.     &lt;br /&gt;
Anzitutto partiamo dal risultato che vorremmo ottenere, ovvero un oggetto che possa registrarsi all’evento del nostro &lt;em&gt;EventSource&lt;/em&gt; in modalità weak, ovvero senza correre il rischio di diventare un potenziale memory leak:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;WeakEventListener &lt;br /&gt;&lt;/span&gt;{             &lt;br /&gt;  &lt;span style="color: blue;"&gt;public &lt;/span&gt;WeakEventListener(&lt;span style="color: rgb(43, 145, 175);"&gt;EventSource &lt;/span&gt;eventSource)     &lt;br /&gt;  {                                                                         &lt;br /&gt;    eventSource.ObservableEvent()                    &lt;br /&gt;               .WeakSubscribe(&lt;span style="color: blue;"&gt;this&lt;/span&gt;, (me, e) =&amp;gt; me.HandleEvent(e.Sender, e.EventArgs));     &lt;br /&gt;  }      &lt;br /&gt;&lt;br /&gt;  &lt;span style="color: blue;"&gt;private void &lt;/span&gt;HandleEvent(&lt;span style="color: blue;"&gt;object &lt;/span&gt;sender, &lt;span style="color: rgb(43, 145, 175);"&gt;EventArgs &lt;/span&gt;eventArgs)     &lt;br /&gt;  {         &lt;br /&gt;    &lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163, 21, 21);"&gt;"WeakEventListener&amp;gt; Event Received!"&lt;/span&gt;);    &lt;br /&gt;  }    &lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;   &lt;br /&gt;
Per ottenere questo risultato le fasi da seguire sono due:&lt;/p&gt;
&lt;p&gt;1) Anzitutto, per leggibilità creiamo un extension method di &lt;em&gt;EventSource&lt;/em&gt; che ne converte l’evento in un &lt;em&gt;IObservable&lt;/em&gt; grazie al classico metodo &lt;a href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.fromeventpattern(v=vs.103).aspx"&gt;Observable.FromEventPattern(...)&lt;/a&gt; di Rx. Dietro le quinte viene creato e restituito un oggetto che sarà in grado di gestire la registrazione e la deregistrazione all’evento, aggiungendo e rimuovendo gli event handlers (strong references) verso l’istanza di &lt;em&gt;EventSource&lt;/em&gt; in esame.  &lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;public static &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IObservable&lt;/span&gt;&amp;lt;EventPattern&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;EventArgs&lt;/span&gt;&amp;gt;&amp;gt; ObservableEvent(&lt;span style="color: blue;"&gt;this &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;EventSource &lt;/span&gt;eventSource) &lt;br /&gt;{    &lt;br /&gt;  &lt;span style="color: blue;"&gt;return &lt;/span&gt;Observable.FromEventPattern&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;EventHandler&lt;/span&gt;, &lt;span style="color: rgb(43, 145, 175);"&gt;EventArgs&lt;/span&gt;&amp;gt;(h =&amp;gt; (s, e) =&amp;gt; h(s, e),&lt;br /&gt;                                                              h =&amp;gt; eventSource.Event += h,&lt;br /&gt;                                                              h =&amp;gt; eventSource.Event -= h); &lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;   &lt;br /&gt;
2) Creiamo un extension method di &lt;em&gt;IObservable&amp;lt;T&amp;gt;&lt;/em&gt; che chiamiamo &lt;em&gt;WeakSubscribe&lt;/em&gt;. Esso ci permette di passare come argomento un oggetto &lt;em&gt;subscriber&lt;/em&gt; ed una &lt;em&gt;action&lt;/em&gt; da eseguire a fronte di una notifica (&lt;em&gt;onNext&lt;/em&gt;) da parte della sequenza osservabile, in modo tale che il &lt;em&gt;subscriber&lt;/em&gt; possa essere notificato tramite l’&lt;em&gt;action&lt;/em&gt; in modalità “weak”, ovvero senza mantenere degli strong reference con la sequenza osservabile.&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;public static &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IDisposable &lt;/span&gt;WeakSubscribe&amp;lt;T, TSubscriber&amp;gt;(&lt;span style="color: blue;"&gt;this &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;IObservable&lt;/span&gt;&amp;lt;T&amp;gt; observable,&lt;br /&gt;                                                        TSubscriber subscriber, &lt;span style="color: rgb(43, 145, 175);"&gt;Action&lt;/span&gt;&amp;lt;TSubscriber, T&amp;gt; action) &lt;br /&gt;                                                        &lt;span style="color: blue;"&gt;where &lt;/span&gt;TSubscriber : &lt;span style="color: blue;"&gt;class &lt;br /&gt;&lt;/span&gt;{     &lt;br /&gt;   &lt;span style="color: blue;"&gt;if &lt;/span&gt;(action.Target != &lt;span style="color: blue;"&gt;null&lt;/span&gt;) &lt;span style="color: blue;"&gt;throw new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;ArgumentException&lt;/span&gt;(&lt;span style="color: rgb(163, 21, 21);"&gt;"action target must NOT refer a class instance, " &lt;/span&gt;+&lt;br /&gt;                                                          &lt;span style="color: rgb(163, 21, 21);"&gt;"in order to avoid a strong reference to target"&lt;/span&gt;);       &lt;br /&gt;   &lt;span style="color: blue;"&gt;var &lt;/span&gt;subscriberWeakReference = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;WeakReference&lt;/span&gt;(subscriber);      &lt;br /&gt;   &lt;span style="color: rgb(43, 145, 175);"&gt;IDisposable &lt;/span&gt;subscription = &lt;span style="color: blue;"&gt;null&lt;/span&gt;;     &lt;br /&gt;   &lt;span style="color: rgb(43, 145, 175);"&gt;Action&lt;/span&gt;&amp;lt;T&amp;gt; onNext = item =&amp;gt;                         &lt;br /&gt;                      {                             &lt;br /&gt;                         &lt;span style="color: blue;"&gt;var &lt;/span&gt;subscriberObj = subscriberWeakReference.Target &lt;span style="color: blue;"&gt;as &lt;/span&gt;TSubscriber;&lt;br /&gt;                         &lt;span style="color: blue;"&gt;if &lt;/span&gt;(subscriberObj != &lt;span style="color: blue;"&gt;null&lt;/span&gt;) action(subscriberObj, item);&lt;br /&gt;                         &lt;span style="color: blue;"&gt;else &lt;/span&gt;subscription.Dispose();&lt;br /&gt;                      };&lt;br /&gt;   subscription = observable.Subscribe(onNext);&lt;br /&gt;   &lt;span style="color: blue;"&gt;return &lt;/span&gt;subscription; &lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;
Qui il gioco si fa interessante ed anche abbastanza complicato: come si osserva, anzitutto il prerequisito è che venga mantenuta una weak reference sul &lt;em&gt;subscriber&lt;/em&gt; tramite una &lt;a href="http://msdn.microsoft.com/en-us/library/system.weakreference.aspx"&gt;WeakReference&lt;/a&gt;. Dopodiché, con una lambda definiamo l’&lt;em&gt;onNext&lt;/em&gt; di un &lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2010/02/26/rx-for-beginners-part-4-anonymous-observer-handler.aspx"&gt;AnonymousObserver&lt;/a&gt; della sequenza osservabile, il quale ad ogni notifica controlla se il &lt;em&gt;subscriber&lt;/em&gt; è ancora vivo (&lt;em&gt;subscriberWeakReference.Target != null&lt;/em&gt;). In caso positivo, viene eseguita l’&lt;em&gt;action&lt;/em&gt; che fa da “passacarte” tra l’observer ed il &lt;em&gt;subscriber&lt;/em&gt;, altrimenti viene chiamata la &lt;em&gt;Dispose()&lt;/em&gt; sulla &lt;em&gt;subscription&lt;/em&gt; dell’observer (il che nel nostro esempio si traduce nella deregistrazione dall’evento dell’&lt;em&gt;EventSource&lt;/em&gt; (&lt;em&gt;eventSource.Event -= h&lt;/em&gt;)).     &lt;br /&gt;
&lt;br /&gt;
Ora arriva il trucco: per evitare che il &lt;em&gt;subscriber&lt;/em&gt; diventi un potenziale memory leak, &lt;em&gt;action.Target&lt;/em&gt; non deve riferire direttamente l’istanza del &lt;em&gt;subscriber&lt;/em&gt;, altrimenti significherebbe che il chiamante del nostro metodo sta passando il puntatore &lt;em&gt;this&lt;/em&gt; su &lt;em&gt;action.Target&lt;/em&gt; (in altre parole,&lt;em&gt; action.Target&lt;/em&gt; == &lt;em&gt;null&lt;/em&gt; significa che il delegato &lt;em&gt;action&lt;/em&gt; invoca un metodo statico e non di istanza). La &lt;em&gt;action&lt;/em&gt; quindi deve essere una lambda che chiama metodi di istanza del &lt;em&gt;subscriber&lt;/em&gt; tramite il riferimento che essa stessa fornisce come parametro, piuttosto che catturare il riferimento implicito a &lt;em&gt;this&lt;/em&gt;:    &lt;br /&gt;
&lt;br /&gt;
.WeakSubscribe(&lt;span style="color: blue;"&gt;this&lt;/span&gt;, (me, e) =&amp;gt; &lt;span style="color: blue;"&gt;&lt;strong&gt;this&lt;/strong&gt;&lt;/span&gt;.HandleEvent(e.Sender, e.EventArgs)); // –&amp;gt; FAIL (ArgumentException)    &lt;br /&gt;
.WeakSubscribe(&lt;span style="color: blue;"&gt;this&lt;/span&gt;, (me, e) =&amp;gt; &lt;strong&gt;me&lt;/strong&gt;.HandleEvent(e.Sender, e.EventArgs)); // –&amp;gt; OK&lt;/p&gt;
&lt;p&gt;Questo controllo ci garantisce che la lambda che poi specifichiamo sull’&lt;em&gt;onNext&lt;/em&gt; non generi una strong reference verso il &lt;em&gt;subscriber&lt;/em&gt; tramite l’&lt;em&gt;action.&lt;/em&gt; Ciò renderebbe il &lt;em&gt;subscriber&lt;/em&gt; un potenziale memory leak. Capiamo meglio il perché: nel nostro esempio, avendo usato un &lt;em&gt;Observable.FromEventPattern&lt;/em&gt;, quando chiamiamo la &lt;em&gt;observable.Subscribe(onNext)&lt;/em&gt; scateniamo internamente la registrazione all’evento dell’&lt;em&gt;EventSource&lt;/em&gt; (&lt;em&gt;h =&amp;gt; eventSource.Event += h&lt;/em&gt;). &lt;em&gt;h&lt;/em&gt; è un EventHandler che tramite una closure interna di Rx crea una strong reference tra l’&lt;em&gt;EventSource&lt;/em&gt; e la &lt;em&gt;onNext&lt;/em&gt;. La &lt;em&gt;onNext&lt;/em&gt; a sua volta mantiene uno strong reference verso la &lt;em&gt;action&lt;/em&gt;. Quindi, a cascata, se l’&lt;em&gt;action&lt;/em&gt; che usiamo nella lambda fosse un metodo di istanza del &lt;em&gt;subscriber,&lt;/em&gt; l’istanza stessa del &lt;em&gt;subscriber&lt;/em&gt; diventerebbe un potenziale memory leak poiché manterrebbe uno strong reference attivo nella &lt;em&gt;subscription&lt;/em&gt;&lt;em&gt;.&lt;/em&gt;    &lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;&lt;font size="3"&gt;&lt;strong&gt;Conclusioni&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Il grande &lt;strong&gt;&lt;u&gt;vantaggio&lt;/u&gt;&lt;/strong&gt; di questa soluzione è che può introdurre in progetti esistenti una semplice gestione thread-safe di weak events al costo di una banale AddReference a &lt;em&gt;System.Reactive.dll&lt;/em&gt;. Infatti, a differenza del “Weak Event Pattern”, questo approccio ha praticamente impatto zero sull’ infrastruttura.     &lt;br /&gt;
L’unico &lt;u&gt;&lt;strong&gt;svantaggio&lt;/strong&gt;&lt;/u&gt; invece è che la &lt;em&gt;subscription.Dispose()&lt;/em&gt; avviene eventualmente sull’ &lt;em&gt;onNext&lt;/em&gt; della sequenza osservabile, il che tradotto nel nostro esempio significa che la deregistrazione dei delegati dall’evento dell’&lt;em&gt;EventSource&lt;/em&gt; avviene eventualmente SOLO a fronte dello scatenare tale evento. Di conseguenza, la &lt;em&gt;onNext&lt;/em&gt; che usiamo per fare &lt;em&gt;observable.Subscribe(&lt;em&gt;onNext&lt;/em&gt;)&lt;/em&gt; potrebbe confluire in dei memory leak fintantoché l’evento non viene scatenato dall’&lt;em&gt;EventSource &lt;/em&gt;(come ho provato a dimostrare con lo Unit test qua sotto). I nostri &lt;em&gt;WeakEventListener&lt;/em&gt; invece vivono felicemente il loro ciclo di vita sicuri di non diventare dei memory leak, poiché ovviamente non sono loro a registrasi direttamente all’evento dell’&lt;em&gt;EventSource&lt;/em&gt;.  &lt;br /&gt;
In conclusione, prima di considerare questa implementazione e comunque in generale, cerchiamo sempre di valutare attentamente qual’è il ciclo di vita degli &lt;em&gt;EventListener&lt;/em&gt; rispetto agli &lt;em&gt;EventSource&lt;/em&gt; :).    &lt;br /&gt;
&lt;/p&gt;
&lt;pre class="code"&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;TestMethod&lt;/span&gt;] &lt;br /&gt;&lt;span style="color: blue;"&gt;public void &lt;/span&gt;WeakEvent_With_Rx() &lt;br /&gt;{    &lt;br /&gt;   &lt;span style="color: blue;"&gt;var &lt;/span&gt;eventSource = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;EventSource&lt;/span&gt;();     &lt;br /&gt;   &lt;span style="color: blue;"&gt;var &lt;/span&gt;strongListener = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;StrongEventListener&lt;/span&gt;(eventSource);     &lt;br /&gt;   &lt;span style="color: blue;"&gt;var &lt;/span&gt;weakListener = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;WeakEventListener&lt;/span&gt;(eventSource);      &lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(43, 145, 175);"&gt;Assert&lt;/span&gt;.AreEqual(2, eventSource.GetEventListenersCount());      &lt;br /&gt;&lt;br /&gt;   eventSource.FireEvent();     &lt;br /&gt;   &lt;span style="color: green;"&gt;// OUTPUT:&lt;br /&gt;   // StrongEventListener&amp;gt; EventReceived!     &lt;br /&gt;   // WeakEventListener&amp;gt; EventReceived!                 &lt;br /&gt;&lt;br /&gt;   &lt;/span&gt;strongListener = &lt;span style="color: blue;"&gt;null&lt;/span&gt;;     &lt;br /&gt;   weakListener = &lt;span style="color: blue;"&gt;null&lt;/span&gt;;      &lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(43, 145, 175);"&gt;GC&lt;/span&gt;.Collect();     &lt;br /&gt;   &lt;span style="color: rgb(43, 145, 175);"&gt;GC&lt;/span&gt;.Collect();     &lt;br /&gt;   &lt;span style="color: rgb(43, 145, 175);"&gt;GC&lt;/span&gt;.WaitForPendingFinalizers();     &lt;br /&gt;   &lt;span style="color: rgb(43, 145, 175);"&gt;GC&lt;/span&gt;.Collect();&lt;br /&gt; &lt;br /&gt;&lt;/pre&gt;
&lt;pre class="code"&gt; &lt;/pre&gt;
&lt;pre class="code"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;   Assert&lt;/span&gt;.AreEqual(2, eventSource.GetEventListenersCount()); &lt;br /&gt;   &lt;span style="color: green;"&gt;// 2 Memory Leak &lt;br /&gt;   // - StrongEventListener has NOT been garbage collected (Obviously)&lt;br /&gt;   // - WeakEventListener has been garbage collected! &lt;br /&gt;   // – onNext action delegate is still a memory leak&lt;/span&gt;&lt;br /&gt;   &lt;br /&gt;&lt;br /&gt;   eventSource.FireEvent();     &lt;br /&gt;   &lt;span style="color: green;"&gt;// OUTPUT: &lt;br /&gt;   // StrongEventListener&amp;gt; EventReceived!      &lt;br /&gt;&lt;br /&gt;   &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Assert&lt;/span&gt;.AreEqual(1, eventSource.GetEventListenersCount()); &lt;br /&gt;   &lt;span style="color: green;"&gt;// 1 Memory Leak (StrongEventListener (Obviously))&lt;/span&gt; &lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;   &lt;br /&gt;
HTH&lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org/dsantarelli/aggbug/100890.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org/dsantarelli/archive/2012/03/25/reactive-extensions-rx-e-weak-events.aspx</guid>
            <pubDate>Sun, 25 Mar 2012 17:15:31 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/dsantarelli/archive/2012/03/25/reactive-extensions-rx-e-weak-events.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/dsantarelli/comments/commentRss/100890.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/dsantarelli/services/trackbacks/100890.aspx</trackback:ping>
        </item>
        <item>
            <title>Spring.NET REST Client</title>
            <link>http://blogs.ugidotnet.org/dsantarelli/archive/2011/12/10/spring.net-rest-client.aspx</link>
            <description>&lt;p&gt;Sono sempre stato un appassionato di soluzioni REST-ful e la nuova versione di &lt;a href="http://www.springframework.net/rest/doc-latest/reference/html/"&gt;Spring.NET REST Client&lt;/a&gt; costituisce a mio avviso un ottimo strumento per implementare il client di un qualunque servizio REST in maniera molto semplice e potente, non solo su framework 2.0/3.5/4.0, ma anche su Silverlight 3 e 4, Compact Framework 2.0/3.5 e Windows Phone 7.     &lt;br /&gt;
Queste API client fanno capo ad una classe di riferimento chiamata &lt;strong&gt;RestTemplate&lt;/strong&gt;. Si tratta a tutti gli effetti di un helper che astrae in maniera molto semplice ognuno dei sei principali metodi HTTP che possono essere supportati da un servizio REST (GET, POST, HEAD, OPTIONS, PUT, DELETE). I metodi di questa classe infatti seguono una&lt;strong&gt; “naming convention”&lt;/strong&gt; in cui la prima parte del metodo indica il verbo HTTP della richiesta e la seconda parte esplicita la rappresentazione della risposta, la quale può essere ad esempio un oggetto deserializzato o l'Uri di una risorsa.     &lt;br /&gt;
Ecco un esempio:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt; var &lt;/span&gt;newCustomer = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Customer &lt;/span&gt;{ FirstName = &lt;span style="color: rgb(163, 21, 21);"&gt;"Dario"&lt;/span&gt;, LastName = &lt;span style="color: rgb(163, 21, 21);"&gt;"Santarelli" &lt;/span&gt;};&lt;/pre&gt;
&lt;pre class="code"&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;RestTemplate &lt;/span&gt;restTemplate = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;RestTemplate&lt;/span&gt;(&lt;span style="color: rgb(163, 21, 21);"&gt;"http://localhost"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre class="code"&gt; &lt;/pre&gt;
&lt;pre class="code"&gt; &lt;span style="color: green;"&gt;// POST (Creates) the Customer resource &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt; &lt;br /&gt; Uri &lt;/span&gt;newCustomerUri = restTemplate.PostForLocation(&lt;span style="color: rgb(163, 21, 21);"&gt;"/myRestService/Customers"&lt;/span&gt;, newCustomer);&lt;/pre&gt;
&lt;pre class="code"&gt; &lt;/pre&gt;
&lt;pre class="code"&gt; &lt;span style="color: green;"&gt;// GET the Customer resource &lt;br /&gt; &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Customer &lt;/span&gt;customerObj = restTemplate.GetForObject&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;Customer&lt;/span&gt;&amp;gt;(newCustomerUri); &lt;span style="color: rgb(43, 145, 175);"&gt; &lt;br /&gt; HttpResponseMessage&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;Customer&lt;/span&gt;&amp;gt; customerMsg = restTemplate.GetForMessage&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;Customer&lt;/span&gt;&amp;gt;(newCustomerUri);&lt;br /&gt;&lt;span style="color: blue;"&gt; string c&lt;/span&gt;ustomerBodyString = restTemplate.GetForObject&amp;lt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;&amp;gt;(newCustomerUri); &lt;br /&gt;&lt;span style="color: blue;"&gt; byte&lt;/span&gt;[] &lt;span style="color: blue;"&gt;c&lt;/span&gt;ustomerBodyBytes = restTemplate.GetForObject&amp;lt;&lt;span style="color: blue;"&gt;byte&lt;/span&gt;[]&amp;gt;(newCustomerUri);&lt;/pre&gt;
&lt;pre class="code"&gt; &lt;/pre&gt;
&lt;pre class="code"&gt; &lt;span style="color: green;"&gt;// DELETE the Customer resource&lt;br /&gt; &lt;/span&gt;restTemplate.Delete(newCustomerUri);&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Anzitutto si chiede al servizio REST di creare una risorsa &lt;em&gt;Customer&lt;/em&gt; tramite il metodo &lt;em&gt;PostForLocation()&lt;/em&gt;, il quale restituisce la Uri della risorsa appena creata, che possiamo quindi accedere con una GET in varie forme: tramite il metodo &lt;em&gt;GetForObject&amp;lt;T&amp;gt;() &lt;/em&gt;potremmo cercare di deserializzare la risposta HTTP direttamente in un oggetto &lt;em&gt;Customer&lt;/em&gt; oppure potremmo ottenerne la rappresentazione raw (es. XML, JSON etc.) specificando il tipo T come &lt;em&gt;string&lt;/em&gt;&lt;em&gt;.&lt;/em&gt; Infine, cancelliamo la risorsa tramite una DELETE. Da notare come &lt;em&gt;GetForObject&amp;lt;T&amp;gt;()&lt;/em&gt; e &lt;em&gt;GetForMessage&amp;lt;T&amp;gt;()&lt;/em&gt; dietro le quinte eseguano entrambi due GET HTTP ma ritornano nel primo caso un oggetto mentre nel secondo caso un message-wrapper di tipo &lt;em&gt;HttpResponseMessage &lt;/em&gt;che espone informazioni aggiuntive come S&lt;em&gt;tatusCode &lt;/em&gt;e &lt;em&gt;Header&lt;/em&gt;. Per questi metodi esistono anche degli overload con il suffisso “Async” per gestire appunto pattern di invocazione asincrona (indispensabili su Silverlight e Windows Phone). &lt;/p&gt;
&lt;p&gt;Per completezza, c’è da dire che per effettuare le chiamate REST si può utilizzare anche un metodo alternativo &lt;em&gt;Exchange()&lt;/em&gt; che permette di interagire direttamente con i verbi HTTP ed oggetti di tipo &lt;em&gt;HttpEntity&lt;/em&gt; (da &lt;a href="http://tools.ietf.org/html/rfc2616#section-7"&gt;specifica HTTP 1.1, section 7&lt;/a&gt;) eventualmente per impostare degli header custom nella richiesta. Ad esempio...&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;HttpEntity &lt;/span&gt;requestEntity = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;HttpEntity&lt;/span&gt;(); &lt;br /&gt;requestEntity.Headers[&lt;span style="color: rgb(163, 21, 21);"&gt;"headerKey"&lt;/span&gt;] = &lt;span style="color: rgb(163, 21, 21);"&gt;"headerValue"&lt;/span&gt;;&lt;/pre&gt;
&lt;pre class="code"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;HttpResponseMessage&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;Customer&lt;/span&gt;&amp;gt; response = restTemplate.Exchange&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;Customer&lt;/span&gt;&amp;gt;(&lt;span style="color: rgb(163, 21, 21);"&gt;"/myRestService/Customers/{id}"&lt;/span&gt;, &lt;br /&gt;                                                                         &lt;span style="color: rgb(43, 145, 175);"&gt;HttpMethod&lt;/span&gt;.GET, requestEntity, 1);&lt;/pre&gt;
&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;string &lt;/span&gt;responseHeader = response.Headers[&lt;span style="color: rgb(163, 21, 21);"&gt;"responseHeaderKey"&lt;/span&gt;]; &lt;br /&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Customer &lt;/span&gt;customer = response.Body; &lt;br /&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;HttpStatusCode &lt;/span&gt;statusCode = response.StatusCode; &lt;br /&gt;&lt;span style="color: blue;"&gt;string &lt;/span&gt;statusDescription = response.StatusDescription;&lt;/pre&gt;
&lt;pre&gt; &lt;/pre&gt;
&lt;p&gt;Per deserializzare correttamente il tipo T specificato ad esempio nei metodi &lt;em&gt;GetForObject&amp;lt;T&amp;gt;() &lt;/em&gt;e &lt;em&gt;GetForMessage&amp;lt;T&amp;gt;(), &lt;/em&gt;il&lt;em&gt; RestTemplate&lt;/em&gt; usa internamente una classe chiamata &lt;em&gt;MessageConverterResponseExtractor&amp;lt;T&amp;gt;&lt;/em&gt; che è in grado di convertire una risposta HTTP in un'istanza di tipo T tramite dei &lt;a href="http://www.springframework.net/rest/doc-latest/reference/html/http-messageconversion.html"&gt;&lt;strong&gt;MessageConverters&lt;/strong&gt;&lt;/a&gt;. A mio avviso la vera potenza di &lt;em&gt;RestTemplate&lt;/em&gt; sta proprio in questa parte, ovvero nel fatto che può essere facilmente configurato per supportare diversi MessageConverters, delle classi il cui ruolo è convertire oggetti in messaggi HTTP e viceversa in base al&lt;em&gt; media type&lt;/em&gt;. Le strategie di conversione sono veramente tante e possono sfruttare sia serializer “standard” del framework come &lt;em&gt;XmlSerializer&lt;/em&gt;, &lt;em&gt;DataContractSerialier&lt;/em&gt;, &lt;em&gt;DataContractJsonSerializer&lt;/em&gt; piuttosto che altre strategie di conversione custom (es. basate su &lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.syndication.syndicationfeed.aspx"&gt;SyndacationFeed&lt;/a&gt; e &lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.syndication.syndicationitem.aspx"&gt;SyndicationItem&lt;/a&gt; per feed ATOM e RSS piuttosto che su &lt;a href="http://json.codeplex.com/"&gt;Json.NET&lt;/a&gt; per accedere ai valori JSON in modo diretto etc.). Ad esempio, possiamo fare in modo che i messaggi HTTP con media type &lt;em&gt;application/json&lt;/em&gt; vengano gestiti dal &lt;em&gt;DataContractJsonSerializer&lt;/em&gt; del framework semplicemente scrivendo…&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;RestTemplate &lt;/span&gt;restTemplate = &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;RestTemplate&lt;/span&gt;(&lt;span style="color: rgb(163, 21, 21);"&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;"http://localhost"&lt;/span&gt;&lt;/span&gt;);&lt;br /&gt;restTemplate.MessageConverters.Add(&lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;JsonHttpMessageConverter&lt;/span&gt;());&lt;/pre&gt;
&lt;pre class="code"&gt;&lt;font color="#2b91af"&gt; &lt;/font&gt;&lt;/pre&gt;
&lt;p&gt;N.B.: i MessageConverters &lt;a href="http://www.springframework.net/rest/doc-latest/reference/html/resttemplate.html#resttemplate-messageconverters"&gt;caricati per default&lt;/a&gt; cambiano in base al target framework di compilazione. Tuttavia, tutti i converter devono implementare l’interfaccia &lt;em&gt;&lt;a href="http://www.springframework.net/rest/doc-latest/reference/html/http-messageconversion.html"&gt;IHttpMessageConverters&lt;/a&gt;,&lt;/em&gt; quindi possiamo facilmente implementarcene uno custom e renderlo operativo in modo molto semplice ed intuitivo.&lt;/p&gt;
&lt;p&gt;Oltre ai MessageConverters , Spring.NET REST Client supporta anche altre features molto interessanti:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;em&gt;RestTemplate&lt;/em&gt; espone una proprietà &lt;a href="http://www.springframework.net/rest/doc-latest/reference/html/resttemplate.html#resttemplate-requestfactory"&gt;RequestFactory&lt;/a&gt; che offre la possibilità di personalizzare il meccanismo di generazione delle richieste HTTP. Per default questa proprietà viene valorizzata con un’ istanza della classe &lt;em&gt;WebClientHttpRequestFactory&lt;/em&gt;, che a sua volta internamente usa la classe &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx"&gt;HttpWebRequest&lt;/a&gt; del framework. Ciò offre gratuitamente la possibilità di supportare proxy HTTP ad esempio. &lt;/li&gt;
    &lt;li&gt;Altra proprietà interessante di &lt;em&gt;RestTemplate&lt;/em&gt; è &lt;a href="http://www.springframework.net/rest/doc-latest/reference/html/resttemplate.html#resttemplate-requestinterceptor"&gt;RequestInterceptors&lt;/a&gt;, ovvero una collezione di interceptors che ci permette di inserirci sia in modo sincorno che in modo asincrono in un qualunque punto della pipeline di crezione ed esecuzione della richiesta HTTP, magari per modificare la richiesta al volo piuttosto che per iniettare gestioni custom di error management, logging, etc. &lt;/li&gt;
&lt;/ul&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:b932ea09-7e47-4452-bfad-e602f6e29ec1" style="margin: 0px; padding: 0px; float: none; display: inline;"&gt;Technorati tags: &lt;a rel="tag" href="http://technorati.com/tags/Spring.NET"&gt;Spring.NET&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/REST"&gt;REST&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org/dsantarelli/aggbug/100613.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org/dsantarelli/archive/2011/12/10/spring.net-rest-client.aspx</guid>
            <pubDate>Sat, 10 Dec 2011 23:29:37 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/dsantarelli/archive/2011/12/10/spring.net-rest-client.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/dsantarelli/comments/commentRss/100613.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/dsantarelli/services/trackbacks/100613.aspx</trackback:ping>
        </item>
        <item>
            <title>[AOP] UI e dintorni con PostSharp</title>
            <link>http://blogs.ugidotnet.org/dsantarelli/archive/2011/10/16/aop-ui-e-dintorni-con-postsharp.aspx</link>
            <description>&lt;p&gt;L’AOP ormai sta diventando un paradigma di programmazione sempre più diffuso specialmente nel mondo .NET dove strumenti come &lt;a href="http://www.postsharp.org/"&gt;PostSharp&lt;/a&gt;, &lt;a href="http://dotspect.tigris.org/"&gt;DotSpect&lt;/a&gt; (&lt;em&gt;Compile-time&lt;/em&gt; s&lt;em&gt;tatic injection) &lt;/em&gt;e &lt;a href="http://www.springframework.net/"&gt;Spring.NET&lt;/a&gt;, &lt;a href="http://www.castleproject.org/container/index.html"&gt;Castle Windsor&lt;/a&gt;, &lt;a href="http://www.codeplex.com/entlib"&gt;Enterprise Library&lt;/a&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/dd139982.aspx"&gt;Policy Injection Application Block&lt;/a&gt; (&lt;em&gt;Dynamic Proxy&lt;/em&gt;) rendono sempre più semplice la gestione dei “&lt;em&gt;&lt;a target="_blank" href="http://en.wikipedia.org/wiki/Cross-cutting_concern"&gt;cross-cutting concerns&lt;/a&gt;&lt;/em&gt;” che provengono dal mondo Object-Oriented. Personalmente sono stato sempre un entusiasta di &lt;a target="_blank" href="http://www.sharpcrafters.com/"&gt;PostSharp&lt;/a&gt; e in questo post vorrei citare un paio di aspect che ho sempre valutato positivamente nella gestione di codice “vicino” alla UI, specialmente nel mondo Windows Forms e WPF.&lt;/p&gt;
&lt;p&gt;Il primo aspect ha a che vedere con il DataBinding. Sappiamo tutti come implementare l’interfaccia &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx"&gt;INotifyPropertyChanged&lt;/a&gt; sia noioso ed anche a fronte di snippet per velocizzare il processo di scrittura il risultato che otteniamo si allontana dall’idea di avere codice (almeno) esteticamente “impeccabile”. Per questo l’aspect che PostSharp introduce a riguardo è tanto semplice quanto geniale in quanto permette, tramite un banale attributo, di agganciare l’implementazione dell’interfaccia &lt;em&gt;INotifyPropertyChanged&lt;/em&gt; ad un oggetto ed eventualmente alle sue specializzazioni. Ad esempio, se definissimo un oggetto &lt;em&gt;Customer&lt;/em&gt; nel seguente modo…&lt;/p&gt;
&lt;pre class="code"&gt;&lt;strong&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;NotifyPropertyChanged&lt;/span&gt;]&lt;/strong&gt; &lt;br /&gt;&lt;span style="color: blue;"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Customer &lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;{   &lt;/span&gt;&lt;/pre&gt;
&lt;pre class="code"&gt;   &lt;span style="color: blue;"&gt;public string &lt;/span&gt;Name { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }   &lt;br /&gt;   &lt;span style="color: blue;"&gt;public string &lt;/span&gt;Surname { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }   &lt;br /&gt;   &lt;span style="color: blue;"&gt;public string &lt;/span&gt;Email { &lt;span style="color: blue;"&gt;get&lt;/span&gt;; &lt;span style="color: blue;"&gt;set&lt;/span&gt;; }&lt;br /&gt;   ... &lt;/pre&gt;
&lt;pre class="code"&gt;}&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;
…tramite l’attributo &lt;em&gt;[NotifyPropertyChanged]&lt;/em&gt; impostato a livello di classe otteniamo nell’assembly di output una injection della solita implementazione dell’interfaccia &lt;em&gt;INotifyPropertyChanged&lt;/em&gt;. L’ implementazione dell’aspect, riportata anche nel sito di PostSharp, è la seguente…&lt;/p&gt;
&lt;pre class="code"&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;Serializable&lt;/span&gt;] &lt;br /&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;IntroduceInterface&lt;/span&gt;(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;INotifyPropertyChanged&lt;/span&gt;),OverrideAction = &lt;span style="color: rgb(43, 145, 175);"&gt;InterfaceOverrideAction&lt;/span&gt;.Ignore)] &lt;br /&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;MulticastAttributeUsage&lt;/span&gt;(&lt;span style="color: rgb(43, 145, 175);"&gt;MulticastTargets&lt;/span&gt;.Class, Inheritance = &lt;span style="color: rgb(43, 145, 175);"&gt;MulticastInheritance&lt;/span&gt;.Strict)] &lt;br /&gt;&lt;span style="color: blue;"&gt;public class &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;NotifyPropertyChangedAttribute &lt;/span&gt;: &lt;span style="color: rgb(43, 145, 175);"&gt;InstanceLevelAspect&lt;/span&gt;, &lt;span style="color: rgb(43, 145, 175);"&gt;INotifyPropertyChanged &lt;br /&gt;&lt;/span&gt;{           &lt;br /&gt;  [&lt;span style="color: rgb(43, 145, 175);"&gt;ImportMember&lt;/span&gt;(&lt;span style="color: rgb(163, 21, 21);"&gt;"OnPropertyChanged"&lt;/span&gt;, IsRequired = &lt;span style="color: blue;"&gt;false&lt;/span&gt;)]    &lt;br /&gt;   &lt;span style="color: blue;"&gt;public &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;&amp;gt; OnPropertyChangedMethod;           &lt;br /&gt;&lt;br /&gt;  [&lt;span style="color: rgb(43, 145, 175);"&gt;IntroduceMember&lt;/span&gt;(Visibility = &lt;span style="color: rgb(43, 145, 175);"&gt;Visibility&lt;/span&gt;.Family, &lt;br /&gt;                   IsVirtual = &lt;span style="color: blue;"&gt;true&lt;/span&gt;, &lt;br /&gt;                   OverrideAction = &lt;span style="color: rgb(43, 145, 175);"&gt;MemberOverrideAction&lt;/span&gt;.Ignore)]    &lt;br /&gt;  &lt;span style="color: blue;"&gt;public void &lt;/span&gt;OnPropertyChanged(&lt;span style="color: blue;"&gt;string &lt;/span&gt;propertyName)    &lt;br /&gt;  {      &lt;br /&gt;    &lt;span style="color: blue;"&gt;if &lt;/span&gt;(&lt;span style="color: blue;"&gt;this&lt;/span&gt;.PropertyChanged != &lt;span style="color: blue;"&gt;null&lt;/span&gt;)       &lt;br /&gt;    {          &lt;br /&gt;      &lt;span style="color: blue;"&gt;this&lt;/span&gt;.PropertyChanged(&lt;span style="color: blue;"&gt;this&lt;/span&gt;.Instance, &lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;PropertyChangedEventArgs&lt;/span&gt;(propertyName));       &lt;br /&gt;    }    &lt;br /&gt;  }           &lt;br /&gt;&lt;br /&gt;  [&lt;span style="color: rgb(43, 145, 175);"&gt;IntroduceMember&lt;/span&gt;(OverrideAction = &lt;span style="color: rgb(43, 145, 175);"&gt;MemberOverrideAction&lt;/span&gt;.Ignore)]    &lt;br /&gt;  &lt;span style="color: blue;"&gt;public event &lt;/span&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;PropertyChangedEventHandler &lt;/span&gt;PropertyChanged;            &lt;br /&gt;&lt;br /&gt;  [&lt;span style="color: rgb(43, 145, 175);"&gt;OnLocationSetValueAdvice&lt;/span&gt;]    &lt;br /&gt;  [&lt;span style="color: rgb(43, 145, 175);"&gt;MulticastPointcut&lt;/span&gt;(Targets = &lt;span style="color: rgb(43, 145, 175);"&gt;MulticastTargets&lt;/span&gt;.Property, Attributes = &lt;span style="color: rgb(43, 145, 175);"&gt;MulticastAttributes&lt;/span&gt;.Instance)]    &lt;br /&gt;  &lt;span style="color: blue;"&gt;public void &lt;/span&gt;OnPropertySet(&lt;span style="color: rgb(43, 145, 175);"&gt;LocationInterceptionArgs &lt;/span&gt;args)    &lt;br /&gt;  {                   &lt;br /&gt;    &lt;span style="color: blue;"&gt;if &lt;/span&gt;(args.Value == args.GetCurrentValue()) &lt;span style="color: blue;"&gt;return&lt;/span&gt;;       &lt;br /&gt;    args.ProceedSetValue();       &lt;br /&gt;    &lt;span style="color: blue;"&gt;this&lt;/span&gt;.OnPropertyChangedMethod.Invoke(args.Location.Name);    &lt;br /&gt;  } &lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;
Il codice è abbastanza autoesplicativo. La feature degna di nota in particolare è la possibilità di estendere automaticamente questo aspect anche alle classi ereditate semplicemente impostando a livello di classe &lt;span style="color: rgb(43, 145, 175);"&gt;MulticastAttributeUsage.&lt;/span&gt;Inheritance = &lt;span style="color: rgb(43, 145, 175);"&gt;MulticastInheritance&lt;/span&gt;.Strict.  &lt;/p&gt;
&lt;p&gt;Un altro aspect che ho sempre ritenuto molto utile ha a che vedere con il thread dispatching, ovvero con la gestione dell’esecuzione di un metodo sul thread dell’interfaccia piuttosto che su un worker thread (es. in WPF controllando il thread associato al &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatchersynchronizationcontext.aspx"&gt;DispatcherSynchronizationContext&lt;/a&gt; corrente). Anche in questo ambito PostSharp permette di definire due attributi&lt;em&gt; &lt;/em&gt;&lt;em&gt;[OnGuiThread]&lt;/em&gt; e &lt;em&gt;[OnWorkerThread]&lt;/em&gt; a livello di metodo, che iniettano la comune logica di controllo del SynchronizationContext in modo da forzare l’esecuzione del metodo rispettivamente sul thread dell’interfaccia o su un thread secondario (&lt;a target="_blank" href="http://www.sharpcrafters.com/solutions/multithreading"&gt;link al codice sorgente&lt;/a&gt;).     &lt;br /&gt;
Come risultato, diventa molto semplice applicare questi aspect anche su codice legacy.&lt;/p&gt;
&lt;pre class="code"&gt;&lt;strong&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;OnWorkerThread&lt;/span&gt;]&lt;/strong&gt; &lt;br /&gt;&lt;span style="color: blue;"&gt;void &lt;/span&gt;SaveCustomer() &lt;br /&gt;{    &lt;br /&gt;  Customer.Save();    &lt;br /&gt;  ShowMessage(&lt;span style="color: rgb(163, 21, 21);"&gt;"Customer Saved!"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre class="code"&gt;}  &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;[&lt;span style="color: rgb(43, 145, 175);"&gt;OnGuiThread&lt;/span&gt;]&lt;/strong&gt; &lt;br /&gt;&lt;span style="color: blue;"&gt;void &lt;/span&gt;ShowMessage(&lt;span style="color: blue;"&gt;string &lt;/span&gt;message) &lt;br /&gt;{ &lt;br /&gt;  &lt;span style="color: rgb(43, 145, 175);"&gt;MessageBox&lt;/span&gt;.Show(message); &lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;
Il pacchetto di istallazione di PostSharp (disponibile anche su &lt;a target="_blank" href="http://nuget.codeplex.com/wikipage?title=Getting%20Started"&gt;NuGet&lt;/a&gt;) aggiunge a Visual Studio due toolbox veramente utili: l’&lt;em&gt;Aspect Browser&lt;/em&gt; che ci permette navigare su quelli che sono gli aspect utilizzati nell’intera solutione e l’ &lt;em&gt;Affected code&lt;/em&gt; toolbox che ci riassume tutte le classi e i metodi che sono soggetti ad aspects. Inoltre, l’intellisense viene esteso in modo da visualizzare dei summary sulle static injections che gli aspect introducono nell’assembly. Ad esempio, per quanto riguarda il precedente aspect &lt;em&gt;NotifyPropertyChanged&lt;/em&gt;, i tooltip che otteniamo sono i seguenti:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://img534.imageshack.us/img534/4948/customer.jpg" /&gt;  &lt;br /&gt;
&lt;img alt="" src="http://img14.imageshack.us/img14/3687/customersetter.png" /&gt; &lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:87428868-7cd2-42df-9e21-563fdb52b8bf" style="margin: 0px; padding: 0px; float: none; display: inline;"&gt;Technorati tags: &lt;a rel="tag" href="http://technorati.com/tags/AOP"&gt;AOP&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/WPF"&gt;WPF&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/GUI"&gt;GUI&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org/dsantarelli/aggbug/100454.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org/dsantarelli/archive/2011/10/16/aop-ui-e-dintorni-con-postsharp.aspx</guid>
            <pubDate>Sun, 16 Oct 2011 21:29:26 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/dsantarelli/archive/2011/10/16/aop-ui-e-dintorni-con-postsharp.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/dsantarelli/comments/commentRss/100454.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/dsantarelli/services/trackbacks/100454.aspx</trackback:ping>
        </item>
        <item>
            <title>[WPF] Drag and Drop con Rx</title>
            <link>http://blogs.ugidotnet.org/dsantarelli/archive/2011/08/25/wpf-drag-and-drop-con-rx.aspx</link>
            <description>Le &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/data/gg577609"&gt;Reactive Extensions (Rx)&lt;/a&gt; del framework .NET sono un set di API dedicate a ciò che nella letteratura prende il nome di “&lt;a href="http://en.wikipedia.org/wiki/Reactive_programming"&gt;reactive programming&lt;/a&gt;”. Rx nasce dalla distinzione di due scenari:
&lt;ul&gt;
    &lt;li&gt;&lt;em&gt;pull&lt;/em&gt;: un programma agisce estraendo dati dall’ambiente in modo interattivo (es. un’iterazione su una sequenza di dati prelevati dall’ambiente).&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;push&lt;/em&gt;: un programma reagisce ai dati che l’ambiente “spinge” verso di esso (es. un event-handler è un esempio di reazione in uno scenario push)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Data questa distinzione, Rx si basa sulla &lt;strong&gt;&lt;a href="http://en.wikipedia.org/wiki/Duality_%28mathematics%29"&gt;&lt;em&gt;dualità&lt;/em&gt;&lt;/a&gt; tra il pattern &lt;a href="http://en.wikipedia.org/wiki/Iterator_pattern"&gt;Iterator&lt;/a&gt; e il pattern &lt;a href="http://en.wikipedia.org/wiki/Observer_pattern"&gt;Observer&lt;/a&gt;&lt;/strong&gt;. In breve, il pattern &lt;em&gt;Observer&lt;/em&gt; in uno scenario &lt;em&gt;push&lt;/em&gt; è analogo al pattern &lt;em&gt;Iterator&lt;/em&gt; in uno scenario &lt;em&gt;pull&lt;/em&gt;.  Nel pattern Iterator, infatti, l’Iterator è l’attore che accede all'insieme degli elementi di un contenitore in modo interattivo. Il pattern Observer può essere interpretato in modo equivalente se si considera che l’ambiente genera spontaneamente i singoli elementi e li spinge verso il programma, ad esempio attraverso eventi. Quando uno stesso evento viene scatenato più volte, di fatto viene prodotta una sequenza di elementi di tipo “evento”, il che rende ovvia a questo punto la relazione con il pattern Iterator.  Rx è stato introdotto quindi per mettere a disposizione degli sviluppatori un modello di programmazione &lt;em&gt;push-based&lt;/em&gt;, duale rispetto al ben più conosciuto &lt;em&gt;pull-based, &lt;/em&gt;pur&lt;em&gt; &lt;/em&gt;non aggiungendo nulla di nuovo rispetto a quest’ultimo. Semplicemente, il modello &lt;em&gt;push-based&lt;/em&gt; offre modi diversi se non più semplici per approcciare problemi comuni legati alla programmazione asincrona ed alla composizione di eventi. &lt;/p&gt;
&lt;p&gt;Rx implementa il pattern Observer tramite le due interfacce &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd783449.aspx"&gt;IObserver&amp;lt;T&amp;gt;&lt;/a&gt; e &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd990377.aspx"&gt;IObservable&amp;lt;T&amp;gt;&lt;/a&gt;, corrispondenti a IEnumerator/IEnumerable del pattern Iterator. IObservable&amp;lt;T&amp;gt; costituisce una sorta di “collezione asincrona” di elementi (generati in momenti diversi quando si parla di eventi). La relazione tra IObservable&amp;lt;T&amp;gt; e IObserver&amp;lt;T&amp;gt; si trova nel fatto che ad un IObservable&amp;lt;T&amp;gt; è possibile registrare uno o più IObserver&amp;lt;T&amp;gt; (tramite il metodo &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd782981.aspx"&gt;IObservable&amp;lt;T&amp;gt;.Subscribe(IObserver&amp;lt;T&amp;gt; observer)&lt;/a&gt; ). IObserver&amp;lt;T&amp;gt; possiede tre metodi: &lt;em&gt;OnNext(…)&lt;/em&gt;, &lt;em&gt;OnCompleted()&lt;/em&gt; e &lt;em&gt;OnError(…)&lt;/em&gt;. Essi vengono invocati dall’ IObservable&amp;lt;T&amp;gt; rispettivamente quando possiede nuovi dati, completa un’operazione e si verifica un errore.  &lt;/p&gt;
&lt;p&gt;&lt;span style="font-size: small;"&gt;&lt;strong&gt;Drag and Drop e LINQ-to-events&lt;/strong&gt;&lt;/span&gt;  &lt;/p&gt;
&lt;p&gt;Nella pratica, uno dei (classici) casi in cui Rx mostra la sua potenza è nell’implementazione del Drag and Drop di un oggetto grafico. Infatti, a differenza delle comuni soluzioni event-based che intercettano eventi e sincronizzano variabili di stato con lo scopo di aggiornare correttamente la posizione dell’oggetto grafico, &lt;span style="text-decoration: underline;"&gt;le Reactive Extensions consentono di convertire gli eventi .NET di interesse in sequenze osservabili che possiamo interrogare tramite query LINQ&lt;/span&gt;.  Vediamo un esempio concreto. Uno dei classici approcci per implementare il drag and drop in WPF (come in Windows Froms o Silverlight) si basa sostanzialmente sulla sincronizzazione di tre eventi logici di un oggetto grafico: &lt;em&gt;MouseDown&lt;/em&gt;, &lt;em&gt;MouseUp&lt;/em&gt; e &lt;em&gt;MouseMove&lt;/em&gt;. Nello specifico, in WPF, supponendo di avere il seguente XAML… &lt;/p&gt;
&lt;pre style="margin: 0px; padding: 0px; width: 100%; font-family: consolas,&amp;quot;Courier New&amp;quot;,courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Window&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;x&lt;/span&gt;:&lt;span style="color: rgb(255, 0, 0);"&gt;Class&lt;/span&gt;=&lt;span style="color: rgb(0, 0, 255);"&gt;"WebRequestWithRxSample.MainWindow"&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px; padding: 0px; font-family: consolas,&amp;quot;Courier New&amp;quot;,courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(255, 0, 0);"&gt;xmlns&lt;/span&gt;="&lt;span style="color: rgb(0, 0, 255);"&gt;http://schemas.microsoft.com/winfx/2006/xaml/presentation&lt;/span&gt;"&lt;/pre&gt;
&lt;pre style="margin: 0px; padding: 0px; font-family: consolas,&amp;quot;Courier New&amp;quot;,courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(255, 0, 0);"&gt;xmlns&lt;/span&gt;:&lt;span style="color: rgb(255, 0, 0);"&gt;x&lt;/span&gt;="&lt;span style="color: rgb(0, 0, 255);"&gt;http://schemas.microsoft.com/winfx/2006/xaml"&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px; padding: 0px; font-family: consolas,&amp;quot;Courier New&amp;quot;,courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(255, 0, 0);"&gt;Title&lt;/span&gt;=&lt;span style="color: rgb(0, 0, 255);"&gt;"MainWindow"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;Loaded&lt;/span&gt;=&lt;span style="color: rgb(0, 0, 255);"&gt;"Window_Loaded"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px; padding: 0px; font-family: consolas,&amp;quot;Courier New&amp;quot;,courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Canvas&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px; padding: 0px; font-family: consolas,&amp;quot;Courier New&amp;quot;,courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;StackPanel&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;Name&lt;/span&gt;=&lt;span style="color: rgb(0, 0, 255);"&gt;"myPanel"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px; padding: 0px; font-family: consolas,&amp;quot;Courier New&amp;quot;,courier,monospace; font-size: 12px;"&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Rectangle&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;Fill&lt;/span&gt;=&lt;span style="color: rgb(0, 0, 255);"&gt;"Maroon"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;Width&lt;/span&gt;=&lt;span style="color: rgb(0, 0, 255);"&gt;"100"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;Height&lt;/span&gt;=&lt;span style="color: rgb(0, 0, 255);"&gt;"100"&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px; padding: 0px; font-family: consolas,&amp;quot;Courier New&amp;quot;,courier,monospace; font-size: 12px;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;StackPanel&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px; padding: 0px; font-family: consolas,&amp;quot;Courier New&amp;quot;,courier,monospace; font-size: 12px;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Canvas&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px; padding: 0px; font-family: consolas,&amp;quot;Courier New&amp;quot;,courier,monospace; font-size: 12px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Window&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;… per gestire il drag and drop dello StackPanel “myPanel” potremmo sincronizzarne i tre eventi &lt;em&gt;MouseLeftButtonDown&lt;/em&gt;, &lt;em&gt;MouseLeftButtonUp&lt;/em&gt; e &lt;em&gt;MouseMove&lt;/em&gt; in modo da gestirne il riposizionamento nel Canvas per ogni evento &lt;em&gt;MouseMove&lt;/em&gt; compreso temporalmente tra un &lt;em&gt;MouseLeftButtonDown&lt;/em&gt; ed un &lt;em&gt;MouseLeftButtonUp&lt;/em&gt;. Quindi, ogni volta che si verifica l’evento &lt;em&gt;MouseLeftButtonDown, &lt;/em&gt;per ogni successivo evento &lt;em&gt;MouseMove&lt;/em&gt; aggiorniamo la posizione dello StackPanel all’interno del Canvas, tenendo conto della posizione del cursore relativa all’angolo in alto a sinistra dello StackPanel. Il tutto finché non viene scatenato l’evento &lt;em&gt;MouseLeftButtonUp&lt;/em&gt;. &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;&lt;span style="font-size: 8.5pt;"&gt;Point&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt; relativeMouseDownPosition = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Point&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;myPanel.MouseLeftButtonDown += (s, e) =&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;  &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt; (myPanel.CaptureMouse())&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;     {&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;          relativeMouseDownPosition = e.GetPosition(myPanel);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;     }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;myPanel.MouseLeftButtonUp += (s, e) =&amp;gt; { myPanel.ReleaseMouseCapture(); };&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;myPanel.MouseMove += (s, e) =&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;   &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;  if&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt; (myPanel.IsMouseCaptured)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;     {&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;       &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    Point&lt;/span&gt; absoluteMousePosition = e.GetPosition(&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;       &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    Point&lt;/span&gt; newPanelPosition = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Point&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;(absoluteMousePosition.X - relativeMouseDownPosition.X,&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;                                                                                 absoluteMousePosition.Y - relativeMouseDownPosition.Y);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;       &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    Canvas&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;.SetLeft(myPanel, newPanelPosition.X);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;       &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;    Canvas&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;.SetTop(myPanel, newPanelPosition.Y);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;   &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0px; line-height: normal;"&gt;&lt;span style="font-family: Courier New;"&gt;&lt;span style="font-size: 8.5pt;"&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Il codice qua sotto implementa la stessa cosa tramite Rx. All’inizio la sintassi può sembrare un po’ meno chiara, ma con il tempo ci si accorge di come in realtà sia molto più leggibile e soprattutto manutenibile rispetto al codice precedente, in quanto si basa su un modello “push” query-based. &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span style="font-size: 8.5pt;"&gt; var &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;relativeMouseDownPositions = &lt;span style="color: rgb(43, 145, 175);"&gt;Observable&lt;/span&gt;.FromEventPattern&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;MouseButtonEventArgs&lt;/span&gt;&amp;gt;(myPanel, &lt;span style="color: rgb(163, 21, 21);"&gt;"MouseLeftButtonDown"&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;)&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;                                      &lt;span style="font-size: 8.5pt;"&gt;.Do(evt =&amp;gt; myPanel.CaptureMouse())&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="font-size: 8.5pt;"&gt;                                             .Select(evt =&amp;gt; evt.EventArgs.GetPosition(myPanel));&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span style="font-size: 8.5pt;"&gt; var &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;mouseUpEvents = &lt;span style="color: rgb(43, 145, 175);"&gt;Observable&lt;/span&gt;.FromEventPattern&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;MouseButtonEventArgs&lt;/span&gt;&amp;gt;(myPanel, &lt;span style="color: rgb(163, 21, 21);"&gt;"MouseLeftButtonUp"&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;)&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;                           &lt;span style="font-size: 8.5pt;"&gt;.Do(evt =&amp;gt; myPanel.ReleaseMouseCapture());&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span style="font-size: 8.5pt;"&gt; var &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;absoluteMousePositions = &lt;span style="color: rgb(43, 145, 175);"&gt;Observable&lt;/span&gt;.FromEventPattern&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;MouseEventArgs&lt;/span&gt;&amp;gt;(myPanel, &lt;span style="color: rgb(163, 21, 21);"&gt;"MouseMove"&lt;/span&gt;) &lt;br /&gt;                                        &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;.Select(evt =&amp;gt; evt.EventArgs.GetPosition(&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;));&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt; &lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;&lt;span style="font-size: 8.5pt;"&gt; IObservable&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;Point&lt;/span&gt;&amp;gt; dragPoints = &lt;span style="color: rgb(0, 0, 255);"&gt;from&lt;/span&gt; relativeMouseDownPosition &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt; relativeMouseDownPositions&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="font-size: 8.5pt;"&gt;                                 &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;from&lt;/span&gt; absoluteMousePosition &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt; absoluteMousePositions.TakeUntil(mouseUpEvents)&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="font-size: 8.5pt;"&gt;                                 &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;select&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Point&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;(absoluteMousePosition.X - relativeMouseDownPosition.X,&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="font-size: 8.5pt;"&gt;                                                  absoluteMousePosition.Y - relativeMouseDownPosition.Y); &lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="font-size: 8.5pt;"&gt; &lt;br /&gt;&lt;br /&gt; dragPoints.ObserveOn(&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;SynchronizationContext&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;.Current).Subscribe(point =&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="font-size: 8.5pt;"&gt; {&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="font-size: 8.5pt;"&gt;    &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Canvas&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;.SetLeft(myPanel, point.X);&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="font-size: 8.5pt;"&gt;    &lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;Canvas&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;.SetTop(myPanel, point.Y);&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="margin: 0px;"&gt;&lt;span style="font-size: 8.5pt;"&gt; });  &lt;/span&gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Alcune considerazioni &lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;La prima cosa che salta all’occhio è come sia possibile convertire un evento .NET in una sequenza osservabile tramite il metodo &lt;span style="color: rgb(43, 145, 175);"&gt;&lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.fromeventpattern(v=vs.103).aspx"&gt;Observable.FromEventPattern&lt;/a&gt;(…)&lt;/span&gt; , il quale permette di specificare il tipo di &lt;em&gt;EventArgs&lt;/em&gt; dell’evento, l’oggetto che espone l’evento da convertire ed il nome dell’evento. In particolare, la seconda riga di codice denota come sia possibile convertire l’evento &lt;em&gt;MouseLeftButtonUp&lt;/em&gt; dello StackPanel in una sequenza osservabile di tipo &lt;span style="color: rgb(43, 145, 175);"&gt;&lt;span style="font-size: 8.5pt;"&gt;IObservable&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;EventPattern&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;MouseButtonEventArgs&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&amp;gt;&amp;gt;&lt;/span&gt;.&lt;/li&gt;
    &lt;li&gt;Rx definisce un suo set di extension methods per comporre sequenze osservabili nello stesso modo in cui LINQ to Objects compone sequenze enumerabili. Ad esempio, il metodo &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/hh229530(v=VS.103).aspx"&gt;Observable.TakeUntil&amp;lt;TSource, TOther&amp;gt;(…)&lt;/a&gt; ritorna tutti gli elementi della sequenza osservabile sorgente finché l’altra sequenza osservabile non produce un valore. Nel nostro esempio, questo extension method è stato usato per filtrare gli eventi &lt;em&gt;MouseMove&lt;/em&gt; tra un evento &lt;em&gt;MouseLeftButtonDown&lt;/em&gt; ed un &lt;em&gt;MouseLeftButtonUp&lt;/em&gt;.&lt;/li&gt;
    &lt;li&gt;Il metodo &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.reactive.linq.observable.observeon(v=VS.103).aspx"&gt;Observable.ObserveOn&amp;lt;TSource&amp;gt;(…)&lt;/a&gt; permette di fare in modo che le notifiche asincrone agli observer vengano effettuate su un thread o uno scheduler specificato. Nel mondo WPF, come in altre piattaforme che supportano un &lt;a target="_blank" href="http://msdn.microsoft.com/it-it/library/system.threading.synchronizationcontext(v=vs.95).aspx"&gt;SynchronizationContext&lt;/a&gt;, per evitare eccezioni cross-thread quando si interagisce con la UI di solito si interagisce con il contesto di sincronizzazione tramite la chiamata &lt;span style="font-size: 8.5pt;"&gt;ObserveOn(&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;&lt;span style="color: rgb(43, 145, 175);"&gt;SynchronizationContext&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8.5pt;"&gt;.Current) &lt;/span&gt;che in WPF in particolare è costituito da un oggetto di tipo &lt;a target="_blank" href="http://msdn.microsoft.com/it-it/library/system.windows.threading.dispatchersynchronizationcontext.aspx"&gt;DispatcherSynchronizationContext&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt; &lt;strong&gt;Note di installazione&lt;/strong&gt;: se stiamo lavorando su Visual Studio 2010, il modo più veloce per integrare Rx nel nostro progetto è &lt;a target="_blank" href="http://www.nuget.org/"&gt;NuGet&lt;/a&gt;. Digitando “Rx” sulla textbox di ricerca dovremmo ottenere la seguente schermata. In particolare, il package &lt;em&gt;Rx-Main&lt;/em&gt; referenzia l’assembly System.Reactive.dll mentre il package &lt;em&gt;Rx-Testing&lt;/em&gt; referenzia l’assembly Microsoft.Reactive.Testing.dll.&lt;/p&gt;
&lt;p&gt;  &lt;img alt="" src="http://img695.imageshack.us/img695/1229/immaginepgx.jpg" /&gt;&lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org/dsantarelli/aggbug/100299.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org/dsantarelli/archive/2011/08/25/wpf-drag-and-drop-con-rx.aspx</guid>
            <pubDate>Thu, 25 Aug 2011 17:27:33 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/dsantarelli/archive/2011/08/25/wpf-drag-and-drop-con-rx.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/dsantarelli/comments/commentRss/100299.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/dsantarelli/services/trackbacks/100299.aspx</trackback:ping>
        </item>
        <item>
            <title>System.Collections.Concurrent: via tutti i lock!</title>
            <link>http://blogs.ugidotnet.org/dsantarelli/archive/2011/07/03/system.collections.concurrent-via-tutti-i-lock.aspx</link>
            <description>&lt;p&gt;Per garantire la &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Thread_safety"&gt;thread-safety&lt;/a&gt; nell’accesso a collezioni di oggetti in contesti multi-thread, fino ad oggi siamo stati abituati ad utilizzare i più svariati meccanismi di lock, magari prevedendo diversi livelli di granularità.    &lt;br /&gt;
In questo ambito il framework 4.0 fornisce il namespace &lt;em&gt;System.Collections.Concurrent&lt;/em&gt; che offre un set di classi thread-safe che si possono usare al posto di quelle di &lt;em&gt;System.Collections&lt;/em&gt; e &lt;em&gt;System.Collections.Generic.&lt;/em&gt; &lt;/p&gt;
&lt;p&gt;Anzitutto, salutiamo con una certa soddisfazione la classe &lt;strong&gt;&lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd287191.aspx"&gt;ConcurrentDictionary&amp;lt;TKey, TValue&amp;gt;&lt;/a&gt;&lt;/strong&gt;, versione thread-safe della classe &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/xfhwa508.aspx"&gt;Dictionary&lt;/a&gt;.    &lt;br /&gt;
&lt;br /&gt;
Vengono forniti poi tre oggetti che implementano &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd287147.aspx"&gt;IProducerConsumerCollection&amp;lt;T&amp;gt;&lt;/a&gt;, un’interfaccia che definisce due metodi &lt;em&gt;TryAdd&lt;/em&gt; e &lt;em&gt;TryTake&lt;/em&gt; per scenari “producer/consumer”, ovvero scenari in cui più thread aggiungono o rimuovono elementi dalla stessa collection in modo concorrente. Gli oggetti in questione sono:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;&lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd381779.aspx"&gt;ConcurrentBag&amp;lt;T&amp;gt;&lt;/a&gt;&lt;/strong&gt;: implementazione thread-safe di una collezione non ordinata di elementi (eventualmente duplicabili). Questo oggetto è particolarmente ottimizzato per scenari in cui lo stesso thread produce e consuma gli elementi del bag.       &lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;&lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd267265.aspx"&gt;ConcurrentQueue&amp;lt;T&amp;gt;&lt;/a&gt;&lt;/strong&gt;: versione concorrente di una coda FIFO. A differenza di quanto si sente dire spesso erroneamente, questa classe non costituisce un semplice wrapper della classe &lt;em&gt;Queue &lt;/em&gt;( tipo &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.collections.queue.synchronized.aspx"&gt;Queue.Synchronized()&lt;/a&gt; ), bensì qualcosa di più potente e performante che internamente fa uso di meccanismi di sincronizzazione e validazione più ottimizzati basati sulle classi &lt;a target="_blank" href="http://msdn.microsoft.com/it-it/library/system.threading.thread.spinwait.aspx"&gt;SpinWait&lt;/a&gt; e &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.threading.interlocked.aspx"&gt;Interlocked&lt;/a&gt;.       &lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;&lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd267331.aspx"&gt;ConcurrentStack&amp;lt;T&amp;gt;&lt;/a&gt;&lt;/strong&gt;: versione concorrente di uno stack LIFO.  &lt;br /&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Infine abbiamo l’oggetto &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd267312.aspx"&gt;&lt;strong&gt;BlockingCollection&amp;lt;T&amp;gt;&lt;/strong&gt;&lt;/a&gt;, che di fatto costituisce una classe di più alto livello. Una &lt;em&gt;BlockingCollection&lt;/em&gt; è a tutti gli effetti un wrapper di un oggetto che implementa l’interfaccia &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd287147.aspx"&gt;IProducerConsumerCollection&amp;lt;T&amp;gt;&lt;/a&gt; (come i sopra citati &lt;em&gt;ConcurrentBag&amp;lt;T&amp;gt;&lt;/em&gt;, &lt;em&gt;ConcurrentQueue&amp;lt;T&amp;gt;&lt;/em&gt; e &lt;em&gt;ConcurrentStack&amp;lt;T&amp;gt;&lt;/em&gt;). Ciò significa che di suo non implementa un meccanismo di storage interno, bensì introduce soltanto la logica di gestione thread-safe per scenari producer/consumer. Infatti, se non forniamo al costruttore un &lt;em&gt;IProducerConsumerCollection&lt;/em&gt;, per default viene istanziata internamente una &lt;em&gt;ConcurrentQueue&lt;/em&gt; (FIFO). Poiché la &lt;em&gt;BlockingCollection&lt;/em&gt; è utile come buffer di scambio condiviso tra più thread, essa fornisce gratis anche dei meccanismi di blocco (metodi &lt;em&gt;&lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd287137.aspx"&gt;Add()&lt;/a&gt;&lt;/em&gt; e &lt;em&gt;&lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/dd287085.aspx"&gt;Take()&lt;/a&gt;&lt;/em&gt;) grazie ai quali possiamo fare in modo che i thread “producer” si blocchino se la collezione è piena (aspettando quindi che almeno un elemento venga rimosso dalla collezione) oppure viceversa che i thread “consumer” si blocchino quando cercano di rimuovere un elemento dalla collection interna vuota.&lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org/dsantarelli/aggbug/100192.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org/dsantarelli/archive/2011/07/03/system.collections.concurrent-via-tutti-i-lock.aspx</guid>
            <pubDate>Sun, 03 Jul 2011 15:31:01 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/dsantarelli/archive/2011/07/03/system.collections.concurrent-via-tutti-i-lock.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/dsantarelli/comments/commentRss/100192.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/dsantarelli/services/trackbacks/100192.aspx</trackback:ping>
        </item>
        <item>
            <title>Validare documenti XHTML con XmlPreloadedResolver</title>
            <link>http://blogs.ugidotnet.org/dsantarelli/archive/2011/04/20/validare-contenuti-xhtml-con-xmlpreloadedresolver-again.aspx</link>
            <description>&lt;p&gt;Una classe molto interessante che ci fornisce il Framework 4.0 è &lt;a target="_blank" href="http://msdn.microsoft.com/it-it/library/system.xml.resolvers.xmlpreloadedresolver(v=VS.100).aspx"&gt;XmlPreloadedResolver&lt;/a&gt;. Come si intuisce dal nome, il suo scopo è quello di risolvere risorse pre-caricate che possono essere referenziate da un’istanza XML. Questa funzionalità è veramente comoda quando non è desiderabile creare chiamate di rete per reperire risorse esterne (es. un DTD) o quando si lavora offline, ricevendo evidenti benefici anche sulle performance.     &lt;br /&gt;
Il plus risiede nel fatto che nell’assembly &lt;em&gt;System.Xml.Utils &lt;/em&gt;sono già “embeddati” i DTD relativi allo standard &lt;strong&gt;XHTML 1.0 Transitional, Strict e Frameset&lt;/strong&gt; (incluse le entities speciali), nonché allo standard &lt;strong&gt;RSS 0.91&lt;/strong&gt;...&lt;/p&gt;
&lt;p&gt;&lt;a target="_blank" href="http://blogs.ugidotnet.org/dsantarelli/archive/2011/04/20/validare-contenuti-xhtml-con-xmlpreloadedresolver.aspx"&gt;Continua &amp;gt;&amp;gt;&lt;/a&gt;  &lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org/dsantarelli/aggbug/99975.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org/dsantarelli/archive/2011/04/20/validare-contenuti-xhtml-con-xmlpreloadedresolver-again.aspx</guid>
            <pubDate>Wed, 20 Apr 2011 21:56:22 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/dsantarelli/archive/2011/04/20/validare-contenuti-xhtml-con-xmlpreloadedresolver-again.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/dsantarelli/comments/commentRss/99975.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/dsantarelli/services/trackbacks/99975.aspx</trackback:ping>
        </item>
        <item>
            <title>Validare documenti XHTML con XmlPreloadedResolver</title>
            <link>http://blogs.ugidotnet.org/dsantarelli/archive/2011/04/20/validare-contenuti-xhtml-con-xmlpreloadedresolver.aspx</link>
            <description>&lt;p&gt;         Una classe molto interessante che ci fornisce il Framework 4.0 è &lt;a target="_blank" href="http://msdn.microsoft.com/it-it/library/system.xml.resolvers.xmlpreloadedresolver(v=VS.100).aspx"&gt;XmlPreloadedResolver&lt;/a&gt;. Come si intuisce dal nome, il suo         scopo è quello di risolvere risorse pre-caricate che possono essere referenziate         da un’istanza XML. Questa funzionalità è veramente comoda quando non è desiderabile         creare chiamate di rete per reperire risorse esterne (es. un DTD) o quando si lavora         offline, con evidenti benefici sulle performance. Un esempio         concreto di utilizzo di questa classe potrebbe intervenire nella validazione di contenuti XHTML 1.x, magari         all’interno di un HttpModule ASP.NET… tipo &lt;a target="_blank" href="http://www.thejoyofcode.com/validator_module.aspx"&gt;questo&lt;/a&gt;.         &lt;br /&gt;
Il plus risiede nel fatto che nell’assembly &lt;em&gt;System.Xml.Utils         &lt;/em&gt;sono già “embeddati” i DTD dello standard &lt;strong&gt;XHTML 1.0 Transitional, Strict             e Frameset&lt;/strong&gt; (incluse le entities speciali), nonché dello standard &lt;strong&gt;RSS                 0.91&lt;/strong&gt;.      &lt;/p&gt;
&lt;p&gt;         &lt;img alt="" src="http://img846.imageshack.us/img846/3001/immaginevj.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Insistendo sul discorso della validazione di contenuti XHTML precaricati, a titolo esemplificativo ho provato a realizzare una semplice         classe &lt;em&gt;XhtmlValidator&lt;/em&gt;, che espone un metodo &lt;em&gt;Validate()&lt;/em&gt; (la validazione         del contenuto) ed il relativo &lt;em&gt;Resolver&lt;/em&gt; (che deve reperire l’eventuale DOCTYPE         esterno da processare nella validazione). &lt;br /&gt;
N.B.: Per versioni del Framework precedenti alla 4.0, possiamo ovviamente decidere di svilupparci in casa un Resolver custom (ereditando la classe         &lt;a target="_blank" href="http://msdn.microsoft.com/it-it/library/system.xml.xmlresolver.aspx"&gt;             XmlResolver&lt;/a&gt;) che sostanzialmente assolva lo stesso compito.&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 8.5pt;"&gt;             public&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font color="#2b91af" style="font-size: 8.5pt;"&gt;XhtmlValidator&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;     &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;   &lt;/font&gt;&lt;/span&gt;             &lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;XmlResolver&lt;/font&gt;&lt;/span&gt;&lt;span&gt; Resolver { &lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;                     get&lt;/font&gt;&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;set&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;; }&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;span style="mso-spacerun: yes;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;              &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;   &lt;/font&gt;&lt;/span&gt;             &lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt; XhtmlValidator() { }&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;   &lt;/font&gt;&lt;/span&gt;             &lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span&gt;                 XhtmlValidator(&lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;XmlResolver&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt; resolver) { Resolver = resolver; }&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;span style="mso-spacerun: yes;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;              &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;   &lt;/font&gt;&lt;/span&gt;             &lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;bool&lt;/font&gt;&lt;/span&gt;&lt;span&gt; Validate(&lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;span&gt;                     xhtml, &lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;out&lt;/font&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;List&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;XmlValidationError&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;&amp;gt; errors)&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;   {&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;              &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;List&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;XmlValidationError&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&amp;gt; validationErrors = &lt;/span&gt;             &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;List&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;XmlValidationError&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;&amp;gt;();                     &lt;/font&gt;&lt;/span&gt;&lt;/font&gt;     &lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;                                                            &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;     &lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;              &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;XmlReaderSettings&lt;/font&gt;&lt;/span&gt;&lt;span&gt;             settings = &lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;XmlReaderSettings&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;();&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;                  settings.ValidationType = &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;ValidationType&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;.DTD;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;                  settings.ValidationFlags = &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;XmlSchemaValidationFlags&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;.ReportValidationWarnings;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;                  settings.DtdProcessing = &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;DtdProcessing&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;.Parse;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;              &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt;&lt;/span&gt;&lt;span&gt;             (Resolver != &lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;null&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;) settings.XmlResolver = Resolver;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;                  settings.ValidationEventHandler += (s, e) =&amp;gt; validationErrors.Add(&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;XmlValidationError&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;(e.Message,e.Severity));                                &lt;/font&gt;&lt;/span&gt;&lt;/font&gt;     &lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;span style="mso-spacerun: yes;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;              &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;              &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;Stream&lt;/font&gt;&lt;/span&gt;&lt;span&gt;             xhtmlStream = &lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;MemoryStream&lt;/font&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;UTF8Encoding&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;.UTF8.GetBytes(xhtml));   &lt;/font&gt;&lt;/span&gt;         &lt;/font&gt;     &lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;span style="mso-spacerun: yes;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;              &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;              &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt;&lt;span&gt;             (&lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;XmlReader&lt;/font&gt;&lt;/span&gt;&lt;span&gt; xmlReader = &lt;/span&gt;             &lt;span&gt;&lt;font color="#2b91af"&gt;XmlReader&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;.Create(xhtmlStream,                 settings)) &lt;/font&gt;&lt;/span&gt;&lt;/font&gt;     &lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;                  { &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;     &lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;                &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;try&lt;/font&gt;&lt;/span&gt;&lt;span&gt;             { &lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;while&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;                 (xmlReader.Read()) ; }&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;                &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;catch&lt;/font&gt;&lt;/span&gt;&lt;span&gt;             (&lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;Exception&lt;/font&gt;&lt;/span&gt;&lt;span&gt; ex) { validationErrors.Add(&lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;XmlValidationError&lt;/font&gt;&lt;/span&gt;&lt;span&gt;(ex.Message,                 &lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;XmlSeverityType&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;.Error)); }                                &lt;/font&gt;&lt;/span&gt;&lt;/font&gt;     &lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;                  }&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;span style="mso-spacerun: yes;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;              &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;                  errors = validationErrors;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;span style="mso-spacerun: yes;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;              &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;              &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt; (validationErrors.Count == 0);&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;    }              &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;     &lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;span style="mso-spacerun: yes;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;              &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;             public&lt;/font&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font color="#2b91af" style="font-size: 8.5pt;"&gt;XmlValidationError&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span /&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;   &lt;/font&gt;&lt;/span&gt;             &lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;span&gt; Message { &lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;                     get&lt;/font&gt;&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;private set&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;; }&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;   &lt;/font&gt;&lt;/span&gt;             &lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;XmlSeverityType&lt;/font&gt;&lt;/span&gt;&lt;span&gt; Severity { &lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;get&lt;/font&gt;&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;private set&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;; }&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;span style="mso-spacerun: yes;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;              &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt;   &lt;/font&gt;&lt;/span&gt;             &lt;font style="font-size: 8.5pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span&gt;                 XmlValidationError(&lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;span&gt; message,                 &lt;/span&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;XmlSeverityType&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8.5pt;"&gt; severity)&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;   {&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;                 Message = message;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;                 Severity = severity;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;   }&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="background: white; margin: 0cm 0cm 0pt; line-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8.5pt;"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;          &lt;/p&gt;
&lt;p&gt;La classe &lt;em&gt;XmlValidationError&lt;/em&gt; è stata introdotta semplicemente come “astrazione”         rispetto a due tipologie di notifiche: quelle derivanti dal parsing della struttura         del documento (le Read() dell’&lt;a target="_blank" href="http://msdn.microsoft.com/it-it/library/system.xml.xmlreader(v=vs.80).aspx"&gt;XmlReader&lt;/a&gt;) e quelle derivanti dal processo di validazione (i ValidationEvent scatenati dalla classe &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.xml.xmlreadersettings.aspx"&gt;XmlReaderSettings&lt;/a&gt;).          &lt;br /&gt;
Vediamo quindi come possiamo sfruttare &lt;em&gt;XmlPreloadedResolver&lt;/em&gt; in questo contesto         tramite una banale applicazione Console…&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font color="#0000ff"&gt;&lt;font style="font-size: 8pt;"&gt;static&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font style="font-size: 8pt;"&gt;                     &lt;span&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt; Main(&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;[]                     args)&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;font style="font-size: 8pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;span style="mso-spacerun: yes;"&gt;&lt;font style="font-size: 8pt;"&gt;   &lt;/font&gt;             &lt;/span&gt;&lt;span&gt;&lt;font color="#008000" style="font-size: 8pt;"&gt;////GOOD XHTML 1.0 (conformant)&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;span style="mso-spacerun: yes;"&gt;&lt;font style="font-size: 8pt;"&gt;   &lt;/font&gt;             &lt;/span&gt;&lt;span&gt;&lt;font color="#008000" style="font-size: 8pt;"&gt;//string xhtml = "&amp;lt;!DOCTYPE                 html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"&amp;gt;"                 +&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;span style="mso-spacerun: yes;"&gt;&lt;font style="font-size: 8pt;"&gt;   &lt;/font&gt;             &lt;/span&gt;&lt;span&gt;&lt;font color="#008000" style="font-size: 8pt;"&gt;//&lt;span style="mso-spacerun: yes;"&gt;                           &lt;/span&gt;"&amp;lt;html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"it\"                 lang=\"it\"&amp;gt;" +&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;span style="mso-spacerun: yes;"&gt;&lt;font style="font-size: 8pt;"&gt;   &lt;/font&gt;             &lt;/span&gt;&lt;span&gt;&lt;font color="#008000" style="font-size: 8pt;"&gt;//&lt;span style="mso-spacerun: yes;"&gt;                           &lt;/span&gt;"&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;GOOD XHTML 1.0 Document&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;p&amp;gt;A                 paragraph here is OK&amp;lt;/p&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;";&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;font style="font-size: 8pt;"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;span style="mso-spacerun: yes;"&gt;&lt;font style="font-size: 8pt;"&gt;   &lt;/font&gt;             &lt;/span&gt;&lt;span&gt;&lt;font color="#008000" style="font-size: 8pt;"&gt;//// BAD XHTML 1.0 (non conformant)&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;span style="mso-spacerun: yes;"&gt;&lt;font style="font-size: 8pt;"&gt;   &lt;/font&gt;             &lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;                 xhtml = &lt;span&gt;&lt;font color="#a31515"&gt;"&amp;lt;!DOCTYPE html PUBLIC \"-//W3C//DTD                     XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"&amp;gt;"&lt;/font&gt;&lt;/span&gt;                 +&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;span style="mso-spacerun: yes;"&gt;&lt;font style="font-size: 8pt;"&gt;                              &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#a31515"&gt;"&amp;lt;html                 xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"it\" lang=\"it\"&amp;gt;"&lt;/font&gt;&lt;/span&gt;                 +&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;span style="mso-spacerun: yes;"&gt;&lt;font style="font-size: 8pt;"&gt;                              &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#a31515"&gt;"&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;BAD                 XHTML 1.0 Document&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;span&amp;gt;A span here                 is NOT OK&amp;lt;/span&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;"&lt;/font&gt;&lt;/span&gt;;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;span style="mso-spacerun: yes;"&gt;             &lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt;                    &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;     &lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;span style="mso-spacerun: yes;"&gt;&lt;font style="font-size: 8pt;"&gt;   &lt;/font&gt;             &lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;XmlPreloadedResolver&lt;/font&gt;&lt;/span&gt;                 resolver = &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;                     XmlPreloadedResolver&lt;/font&gt;&lt;/span&gt;(&lt;span&gt;&lt;font color="#2b91af"&gt;XmlKnownDtds&lt;/font&gt;&lt;/span&gt;.Xhtml10);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;span style="mso-spacerun: yes;"&gt;&lt;font style="font-size: 8pt;"&gt;   &lt;/font&gt;             &lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;XhtmlValidator&lt;/font&gt;&lt;/span&gt;                 validator = &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;                     XhtmlValidator&lt;/font&gt;&lt;/span&gt;(resolver);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;font style="font-size: 8pt;"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;span style="mso-spacerun: yes;"&gt;&lt;font style="font-size: 8pt;"&gt;   &lt;/font&gt;             &lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;List&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;XmlValidationError&lt;/font&gt;&lt;/span&gt;&amp;gt; validationErrors = &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;List&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#2b91af"&gt;XmlValidationError&lt;/font&gt;&lt;/span&gt;&amp;gt;();&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;span style="mso-spacerun: yes;"&gt;&lt;font style="font-size: 8pt;"&gt;   &lt;/font&gt;             &lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;bool&lt;/font&gt;&lt;/span&gt; success                 = validator.Validate(xhtml, &lt;span&gt;&lt;font color="#0000ff"&gt;out&lt;/font&gt;&lt;/span&gt; validationErrors);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;font style="font-size: 8pt;"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;span style="mso-spacerun: yes;"&gt;&lt;font style="font-size: 8pt;"&gt;   &lt;/font&gt;             &lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt;&lt;/span&gt; (success)                 &lt;span&gt;&lt;font color="#2b91af"&gt;Console&lt;/font&gt;&lt;/span&gt;.WriteLine(&lt;span&gt;&lt;font color="#a31515"&gt;"Success"&lt;/font&gt;&lt;/span&gt;);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;span style="mso-spacerun: yes;"&gt;&lt;font style="font-size: 8pt;"&gt;   &lt;/font&gt;             &lt;/span&gt;&lt;span&gt;&lt;font color="#0000ff" style="font-size: 8pt;"&gt;else&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;span style="mso-spacerun: yes;"&gt;&lt;font style="font-size: 8pt;"&gt;   &lt;/font&gt;             &lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;span style="mso-spacerun: yes;"&gt;&lt;font style="font-size: 8pt;"&gt;                  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;Console&lt;/font&gt;&lt;/span&gt;.WriteLine(&lt;span&gt;&lt;font color="#a31515"&gt;"Errors: "&lt;/font&gt;&lt;/span&gt; + validationErrors.Count.ToString());&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;span&gt;&lt;font face="Courier New"&gt;             &lt;span style="mso-spacerun: yes;"&gt;&lt;font style="font-size: 8pt;"&gt;                  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;foreach&lt;/font&gt;&lt;/span&gt;                 (&lt;span&gt;&lt;font color="#2b91af"&gt;XmlValidationError &lt;/font&gt;&lt;/span&gt;error &lt;span&gt;&lt;font color="#0000ff"&gt;                     in&lt;/font&gt;&lt;/span&gt; validationErrors) &lt;span&gt;&lt;font color="#2b91af"&gt;Console&lt;/font&gt;&lt;/span&gt;.WriteLine(&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;.Format(&lt;span&gt;&lt;font color="#a31515"&gt;"- Message:                             {0} (Severity: {1})"&lt;/font&gt;&lt;/span&gt;, error.Message, error.Severity));&lt;/font&gt;&lt;span style="mso-spacerun: yes;"&gt;&lt;font style="font-size: 8pt;"&gt;                                                &lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;     &lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal; mso-layout-grid-align: none;"&gt;         &lt;font face="Courier New"&gt;&lt;span&gt;             &lt;span style="mso-spacerun: yes;"&gt;&lt;font style="font-size: 8pt;"&gt;   &lt;/font&gt;             &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: ;"&gt;&lt;font style="font-size: 8pt;"&gt;}&lt;/font&gt;&lt;span style="mso-spacerun: yes;"&gt;&lt;font style="font-size: 8pt;"&gt;                           &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;     &lt;/p&gt;
&lt;span style="line-height: 9pt; font-family: ; mso-ansi-language: it; mso-fareast-language: en-us; mso-bidi-language: ar-sa; mso-fareast-font-family: calibri; mso-fareast-theme-font: minor-latin;"&gt;         &lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;
&lt;p&gt;          &lt;/p&gt;
&lt;p&gt;         Eseguendo il codice precedente senza essere connessi alla rete, si osserva come il         &lt;em&gt;XmlPreloadedResolver&lt;/em&gt; faccia il suo lavoro e ci permetta di validare il contenuto         XHTML 1.0 Strict di esempio tramite il relativo DTD embeddato nell’assembly &lt;em&gt;System.Xml.Utils&lt;/em&gt;.     &lt;/p&gt;
&lt;p&gt;         &lt;img alt="" src="http://img17.imageshack.us/img17/3971/immaginelab.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;         &lt;strong&gt;&lt;em&gt;Domanda&lt;/em&gt;&lt;/strong&gt;: E se volessimo usare &lt;em&gt;XmlPreloadedResolver&lt;/em&gt; su documenti &lt;strong&gt;XHTML 1.1&lt;/strong&gt;?         &lt;br /&gt;
Ebbene, sembra che la strada dello standard XHTML 1.1 non sia stata battuta, forse per la         forte modularizzazione della specifica o forse per l'effettiva scarsa         adozione dello standard nel web. Fatto sta che in questo contesto non abbiamo "known" DTD         pre-caricati (neanche quelli “core” definiti nel &lt;a target="_blank" href="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"&gt;DTD principale&lt;/a&gt;), quindi dobbiamo pre-caricarceli “a mano”         in questo modo…     &lt;/p&gt;
&lt;p&gt;         &lt;br /&gt;
&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font color="#2b91af"&gt;&lt;font style="font-size: 8pt;"&gt;XmlPreloadedResolver&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font style="font-size: 8pt;"&gt;                     xmlPreloadedResolver = &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;XmlPreloadedResolver&lt;/font&gt;&lt;/span&gt;(&lt;span&gt;&lt;font color="#2b91af"&gt;XmlKnownDtds&lt;/font&gt;&lt;/span&gt;.Xhtml10);                     &lt;br /&gt;
&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span&gt;                     &lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt;xmlPreloadedResolver.Add(&lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;Uri&lt;/font&gt;&lt;/span&gt;(&lt;span&gt;&lt;font color="#a31515"&gt;"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"&lt;/font&gt;&lt;/span&gt;),                         &lt;span&gt;&lt;font color="#2b91af"&gt;File&lt;/font&gt;&lt;/span&gt;.ReadAllBytes(&lt;span&gt;&lt;font color="#a31515"&gt;"C:\\...\\xhtml11.dtd"&lt;/font&gt;&lt;/span&gt;));                         &lt;br /&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;                         &lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt;xmlPreloadedResolver.Add(&lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;Uri&lt;/font&gt;&lt;/span&gt;(&lt;span&gt;&lt;font color="#a31515"&gt;"http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-inlstyle-1.mod"&lt;/font&gt;&lt;/span&gt;),                             &lt;span&gt;&lt;font color="#2b91af"&gt;File&lt;/font&gt;&lt;/span&gt;.ReadAllBytes(&lt;span&gt;&lt;font color="#a31515"&gt;"C:\\...\\xhtml-inlstyle-1.mod"&lt;/font&gt;&lt;/span&gt;));                             &lt;br /&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;                             &lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt;xmlPreloadedResolver.Add(&lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;Uri&lt;/font&gt;&lt;/span&gt;(&lt;span&gt;&lt;font color="#a31515"&gt;"http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-text-1.mod"&lt;/font&gt;&lt;/span&gt;),                                 &lt;span&gt;&lt;font color="#2b91af"&gt;File&lt;/font&gt;&lt;/span&gt;.ReadAllBytes(&lt;span&gt;&lt;font color="#a31515"&gt;"C:\\...\\xhtml-text-1.mod"&lt;/font&gt;&lt;/span&gt;));                                 &lt;br /&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;                                 &lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt;xmlPreloadedResolver.Add(&lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;Uri&lt;/font&gt;&lt;/span&gt;(&lt;span&gt;&lt;font color="#a31515"&gt;"http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-hypertext-1.mod"&lt;/font&gt;&lt;/span&gt;),                                     &lt;span&gt;&lt;font color="#2b91af"&gt;File&lt;/font&gt;&lt;/span&gt;.ReadAllBytes(&lt;span&gt;&lt;font color="#a31515"&gt;"C:\\...\\xhtml-hypertext-1.mod"&lt;/font&gt;&lt;/span&gt;));                                     &lt;br /&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;                                     &lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt;xmlPreloadedResolver.Add(&lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;Uri&lt;/font&gt;&lt;/span&gt;(&lt;span&gt;&lt;font color="#a31515"&gt;"http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-list-1.mod"&lt;/font&gt;&lt;/span&gt;),                                         &lt;span&gt;&lt;font color="#2b91af"&gt;File&lt;/font&gt;&lt;/span&gt;.ReadAllBytes(&lt;span&gt;&lt;font color="#a31515"&gt;"C:\\...\\xhtml-list-1.mod"&lt;/font&gt;&lt;/span&gt;));                                         &lt;br /&gt;
etc... &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;     &lt;/p&gt;
&lt;p&gt;          &lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:f1996e40-eea3-44ef-8a1f-fee1e6307ac7" style="margin: 0px; padding: 0px; float: none; display: inline;"&gt;         Tag di Technorati: &lt;a rel="tag" href="http://technorati.com/tags/XHTML"&gt;XHTML&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/.NET"&gt;.NET&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/C%23"&gt;C#&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/DTD"&gt;DTD&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org/dsantarelli/aggbug/99974.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org/dsantarelli/archive/2011/04/20/validare-contenuti-xhtml-con-xmlpreloadedresolver.aspx</guid>
            <pubDate>Wed, 20 Apr 2011 21:23:22 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/dsantarelli/archive/2011/04/20/validare-contenuti-xhtml-con-xmlpreloadedresolver.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/dsantarelli/comments/commentRss/99974.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/dsantarelli/services/trackbacks/99974.aspx</trackback:ping>
        </item>
        <item>
            <title>Dictionary persistenti</title>
            <link>http://blogs.ugidotnet.org/dsantarelli/archive/2010/10/23/dictionary-persistenti-again.aspx</link>
            <description>&lt;p&gt;In questo post ho cercato di riportare la mia esperienza nella modellizzazione di dictionary persistenti in un progetto reale. In particolare, viene descritta una soluzione in cui è stato ritenuto necessario definire un livello di astrazione che permettesse di derivare implementazioni concrete di dictionary persistenti su file system.    &lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://blogs.ugidotnet.org/dsantarelli/archive/2010/10/22/dictionary-persistenti.aspx"&gt;Leggi il post&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org/dsantarelli/aggbug/99390.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org/dsantarelli/archive/2010/10/23/dictionary-persistenti-again.aspx</guid>
            <pubDate>Sat, 23 Oct 2010 01:14:42 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/dsantarelli/archive/2010/10/23/dictionary-persistenti-again.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/dsantarelli/comments/commentRss/99390.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/dsantarelli/services/trackbacks/99390.aspx</trackback:ping>
        </item>
        <item>
            <title>Dictionary persistenti</title>
            <link>http://blogs.ugidotnet.org/dsantarelli/archive/2010/10/23/dictionary-persistenti.aspx</link>
            <description>&lt;p&gt;     In un mio progetto avevo bisogno di rendere persistenti dei Dictionary al fine di     recuperarne lo stato al riavvio dell’applicazione. Poiché avevo bisogno     di gestire un livello di astrazione rispetto allo storage utilizzato, ho anzitutto     definito una classe astratta &lt;em&gt;PersistentDictionary&amp;lt;TKey,TValue&amp;gt;&lt;/em&gt; derivando     &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/xfhwa508.aspx"&gt;Dictionary&amp;lt;TKey,TValue&amp;gt;&lt;/a&gt;     nel seguente modo:&lt;/p&gt;
&lt;span lang="EN-US"&gt;&lt;font face="Courier New"&gt;&lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 8pt;"&gt;         public&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font style="font-size: 8pt;"&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;abstract&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;PersistentDictionary&lt;/font&gt;&lt;/span&gt;&amp;lt;TKey,             TValue&amp;gt; : &lt;span&gt;&lt;font color="#2b91af"&gt;Dictionary&lt;/font&gt;&lt;/span&gt;&amp;lt;TKey, TValue&amp;gt;             &lt;br /&gt;
&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;             &lt;font style="font-size: 8pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;       &lt;br /&gt;
&lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;         &lt;font style="font-size: 8pt;"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;             &lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;abstract&lt;/font&gt;&lt;/span&gt;             &lt;span&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt; Load();             &lt;br /&gt;
    &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-family: courier new;"&gt;                 &lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;                     &lt;span&gt;&lt;font color="#0000ff"&gt;abstract&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt;                     Save();&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8pt;"&gt;    &lt;/font&gt;&lt;/span&gt;                 &lt;/font&gt;&lt;/span&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt;             }&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;         &lt;br /&gt;
Come è facile intuire, i metodi &lt;em&gt;Load()&lt;/em&gt; e &lt;em&gt;Save()&lt;/em&gt; servono         per leggere/scrivere i dati del dictionary dallo/sullo storage.         &lt;br /&gt;
Nella mia soluzione avevo la necessità di persistere su file system le coppie         chiave/valore supportando diversi formati. Ho quindi creato un altro livello di         astrazione per rappresentare i dictionary persistenti su file system.     &lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;font face="Courier New"&gt;&lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 8pt;"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font style="font-size: 8pt;"&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;                     abstract&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;FileDictionary&lt;/font&gt;&lt;/span&gt;&amp;lt;TKey, TValue&amp;gt; : &lt;span&gt;&lt;font color="#2b91af"&gt;                             PersistentDictionary&lt;/font&gt;&lt;/span&gt;&amp;lt;TKey, TValue&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;         &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;             FileName { &lt;span&gt;&lt;font color="#0000ff"&gt;get&lt;/font&gt;&lt;/span&gt;; &lt;span&gt;&lt;font color="#0000ff"&gt;                 private&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;set&lt;/font&gt;&lt;/span&gt;; }&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;          &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt; FileDictionary(&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;                 fileName)&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;     &lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt;  {&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt;&lt;/span&gt; (&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;.IsNullOrWhiteSpace(fileName))                 &lt;span&gt;&lt;font color="#0000ff"&gt;throw&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;                 &lt;span&gt;&lt;font color="#2b91af"&gt;ArgumentException&lt;/font&gt;&lt;/span&gt;(&lt;span&gt;&lt;font color="#a31515"&gt;"filename                     can't be null or empty"&lt;/font&gt;&lt;/span&gt;);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;font face="Courier New"&gt;&lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: courier new;"&gt;&lt;font style="font-size: 8pt;"&gt;FileName = fileName;&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8pt;"&gt;        &lt;/font&gt;&lt;/span&gt;             &lt;/span&gt;&lt;/font&gt;     &lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8pt;"&gt;               &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt;             }&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;         &lt;br /&gt;
Questo tipo di approccio mi ha permesso di lasciare la porta aperta a diverse personalizzazioni.         Ad esempio, la seguente classe &lt;em&gt;XmlFileDictionary&amp;lt;TKey,TValue&amp;gt;&lt;/em&gt; può         essere utilizzata per serializzare/deserializzare in modo generico le coppie chiave/valore         di qualunque tipo su un file XML sfruttando la classe &lt;a target="_blank" href="http://msdn.microsoft.com/it-it/library/system.xml.serialization.xmlserializer(VS.80).aspx"&gt;             XmlSerializer&lt;/a&gt; (scelta per rimanere retrocompatibile con il framework 2.0).&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;XmlFileDictionary&lt;/font&gt;&lt;/span&gt;&amp;lt;TKey,             TValue&amp;gt; : &lt;span&gt;&lt;font color="#2b91af"&gt;FileDictionary&lt;/font&gt;&lt;/span&gt;&amp;lt;TKey, TValue&amp;gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;                 &lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;XmlSerializer&lt;/font&gt;&lt;/span&gt;                 keySerializer;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;                 &lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;XmlSerializer&lt;/font&gt;&lt;/span&gt;                 valueSerializer;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;                 &lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt; XmlFileDictionary(&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;                 fileName) : &lt;span&gt;&lt;font color="#0000ff"&gt;base&lt;/font&gt;&lt;/span&gt;(fileName)&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;                 keySerializer = &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;                     XmlSerializer&lt;/font&gt;&lt;/span&gt;(&lt;span&gt;&lt;font color="#0000ff"&gt;typeof&lt;/font&gt;&lt;/span&gt;(TKey));&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;                 valueSerializer = &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;                     XmlSerializer&lt;/font&gt;&lt;/span&gt;(&lt;span&gt;&lt;font color="#0000ff"&gt;typeof&lt;/font&gt;&lt;/span&gt;(TValue));&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8pt;"&gt;                                &lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;     &lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt;                     &lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;override&lt;/font&gt;&lt;/span&gt;                     &lt;span&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt; Load()&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;      &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt;&lt;/span&gt; (&lt;span&gt;&lt;font color="#2b91af"&gt;File&lt;/font&gt;&lt;/span&gt;.Exists(&lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;.FileName))&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;      &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;        &lt;/font&gt;         &lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;.Clear();&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;         &lt;/font&gt;         &lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt;             (&lt;span&gt;&lt;font color="#2b91af"&gt;XmlReader&lt;/font&gt;&lt;/span&gt; reader = &lt;span&gt;&lt;font color="#2b91af"&gt;                 XmlReader&lt;/font&gt;&lt;/span&gt;.Create(&lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;.FileName))&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;         &lt;/font&gt;         &lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                       &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;reader.ReadToFollowing(&lt;span&gt;&lt;font color="#a31515"&gt;"dictionary"&lt;/font&gt;&lt;/span&gt;);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                       &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt;&lt;/span&gt;                 (!reader.IsEmptyElement)&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                       &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                         &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;reader.ReadToFollowing(&lt;span&gt;&lt;font color="#a31515"&gt;"item"&lt;/font&gt;&lt;/span&gt;);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                         &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;while&lt;/font&gt;&lt;/span&gt;                 (reader.NodeType != &lt;span&gt;&lt;font color="#2b91af"&gt;XmlNodeType&lt;/font&gt;&lt;/span&gt;.EndElement)&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                         &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                           &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;reader.ReadStartElement(&lt;span&gt;&lt;font color="#a31515"&gt;"item"&lt;/font&gt;&lt;/span&gt;);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                           &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;reader.ReadStartElement(&lt;span&gt;&lt;font color="#a31515"&gt;"key"&lt;/font&gt;&lt;/span&gt;);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                           &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;TKey key = (TKey)keySerializer.Deserialize(reader);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                           &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;reader.ReadEndElement();&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                           &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;reader.ReadStartElement(&lt;span&gt;&lt;font color="#a31515"&gt;"value"&lt;/font&gt;&lt;/span&gt;);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                           &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;TValue value = (TValue)valueSerializer.Deserialize(reader);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;font face="Courier New"&gt;&lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                           &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: courier new;"&gt;&lt;font style="font-size: 8pt;"&gt;                 reader.ReadEndElement();&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8pt;"&gt;                           &lt;/font&gt;         &lt;/span&gt;&lt;span&gt;&lt;font style="font-size: 8pt;"&gt;                      &lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;     &lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8pt;"&gt;                                    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;reader.ReadEndElement();&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt;              &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                           &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;.Add(key,                 value);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                         &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;}&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8pt;"&gt;                                    &lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;     &lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                       &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;         &lt;/font&gt;         &lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;      &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt;                     &lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;override&lt;/font&gt;&lt;/span&gt;                     &lt;span&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt; Save()&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;{&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8pt;"&gt;                       &lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;     &lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;     &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;                 &lt;span&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt; (&lt;span&gt;&lt;font color="#2b91af"&gt;XmlWriter&lt;/font&gt;&lt;/span&gt;                 writer = &lt;span&gt;&lt;font color="#2b91af"&gt;XmlWriter&lt;/font&gt;&lt;/span&gt;.Create(&lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;.FileName))&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;     &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;                 {&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8pt;"&gt;                                &lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;     &lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;        &lt;/font&gt;         &lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;writer.WriteStartDocument();&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;        &lt;/font&gt;         &lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;writer.WriteStartElement(&lt;span&gt;&lt;font color="#a31515"&gt;"dictionary"&lt;/font&gt;&lt;/span&gt;,             &lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;.Empty);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;        &lt;/font&gt;         &lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;foreach&lt;/font&gt;&lt;/span&gt;             (TKey key &lt;span&gt;&lt;font color="#0000ff"&gt;in&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;.Keys)&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;        &lt;/font&gt;         &lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                       &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;writer.WriteStartElement(&lt;span&gt;&lt;font color="#a31515"&gt;"item"&lt;/font&gt;&lt;/span&gt;);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                       &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;writer.WriteStartElement(&lt;span&gt;&lt;font color="#a31515"&gt;"key"&lt;/font&gt;&lt;/span&gt;);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                           k&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;eySerializer.Serialize(writer, key);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                       &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;writer.WriteEndElement();&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                       &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;writer.WriteStartElement(&lt;span&gt;&lt;font color="#a31515"&gt;"value"&lt;/font&gt;&lt;/span&gt;);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;        &lt;/font&gt;         &lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;   &lt;/span&gt;valueSerializer.Serialize(writer,             &lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;[key]);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                       &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;writer.WriteEndElement();&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;                       &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;writer.WriteEndElement();&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;        &lt;/font&gt;         &lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;        &lt;/font&gt;         &lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;writer.WriteEndElement();&lt;/font&gt;&lt;span&gt;&lt;font style="font-size: 8pt;"&gt;                        &lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;     &lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;font face="Courier New"&gt;&lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;     &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: courier new;"&gt;&lt;font style="font-size: 8pt;"&gt;}&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;&lt;font style="font-size: 8pt;"&gt;               &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt;             }&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;         &lt;br /&gt;
Nel mio progetto inoltre ho dovuto gestire vari manifest per memorizzare degli indici         di cache, sempre su file system. In ciascun file, sia le chiavi che i valori sono         sempre di tipo stringa ed ogni coppia è memorizzata su una linea terminata         da CRLF. Ho potuto quindi riutilizzare l’astrazione &lt;em&gt;FileDictionary&amp;lt;TKey,             TValue&amp;gt;&lt;/em&gt; sopra citata per definire una classe concreta che rappresenta         un manifest file.&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;font face="Courier New"&gt;&lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font color="#0000ff"&gt;&lt;font style="font-size: 8pt;"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font style="font-size: 8pt;"&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;                     class&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;ManifestFile&lt;/font&gt;&lt;/span&gt; : &lt;span&gt;&lt;font color="#2b91af"&gt;FileDictionary&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;,                     &lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&amp;gt;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;                 &lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;const&lt;/font&gt;&lt;/span&gt;                 &lt;span&gt;&lt;font color="#0000ff"&gt;char&lt;/font&gt;&lt;/span&gt; DEFAULT_SEPARATOR = &lt;span&gt;&lt;font color="#a31515"&gt;                     '|'&lt;/font&gt;&lt;/span&gt;;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;                 &lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;char&lt;/font&gt;&lt;/span&gt;                 _separator;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;                 &lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;Encoding&lt;/font&gt;&lt;/span&gt;                 _encoding;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;                 &lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt; ManifestFile(&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;                 fileName) : &lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;(fileName, DEFAULT_SEPARATOR,                 &lt;span&gt;&lt;font color="#2b91af"&gt;Encoding&lt;/font&gt;&lt;/span&gt;.Default) { }&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;                 &lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt; ManifestFile(&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;                 fileName, &lt;span&gt;&lt;font color="#0000ff"&gt;char&lt;/font&gt;&lt;/span&gt; separator) : &lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;(fileName, separator, &lt;span&gt;&lt;font color="#2b91af"&gt;                         Encoding&lt;/font&gt;&lt;/span&gt;.Default) { }&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;                 &lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt; ManifestFile(&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;                 fileName, &lt;span&gt;&lt;font color="#0000ff"&gt;char&lt;/font&gt;&lt;/span&gt; separator, &lt;span&gt;&lt;font color="#2b91af"&gt;                     Encoding&lt;/font&gt;&lt;/span&gt; encoding) : &lt;span&gt;&lt;font color="#0000ff"&gt;base&lt;/font&gt;&lt;/span&gt;(fileName)&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;                 &lt;span&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt;&lt;/span&gt; (encoding == &lt;span&gt;&lt;font color="#0000ff"&gt;                     null&lt;/font&gt;&lt;/span&gt;) &lt;span&gt;&lt;font color="#0000ff"&gt;throw&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;                         new&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;ArgumentNullException&lt;/font&gt;&lt;/span&gt;(&lt;span&gt;&lt;font color="#a31515"&gt;"encoding can't be null"&lt;/font&gt;&lt;/span&gt;);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;                 _separator = separator;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;                 _encoding = encoding;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;                 &lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;override&lt;/font&gt;&lt;/span&gt;                 &lt;span&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt; Load()&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;                 &lt;span&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt;&lt;/span&gt; (&lt;span&gt;&lt;font color="#2b91af"&gt;File&lt;/font&gt;&lt;/span&gt;.Exists(&lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;.FileName))&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;                 {&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;      &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;.Clear();&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;      &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;[] lines                 = &lt;span&gt;&lt;font color="#2b91af"&gt;File&lt;/font&gt;&lt;/span&gt;.ReadAllLines(&lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;.FileName,                 _encoding);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;      &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;foreach&lt;/font&gt;&lt;/span&gt; (&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; line &lt;span&gt;&lt;font color="#0000ff"&gt;in&lt;/font&gt;&lt;/span&gt;                 lines)&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;      &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;        &lt;/font&gt;         &lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;[]             parts = line.Split(&lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;                 char&lt;/font&gt;&lt;/span&gt;[] { _separator }, &lt;span&gt;&lt;font color="#2b91af"&gt;StringSplitOptions&lt;/font&gt;&lt;/span&gt;.RemoveEmptyEntries);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;        &lt;/font&gt;         &lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;.Add(parts[0],             parts[1]);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;      &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;                 }&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;                 &lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#0000ff"&gt;override&lt;/font&gt;&lt;/span&gt;                 &lt;span&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt; Save()&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;{&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;                 &lt;span&gt;&lt;font color="#0000ff"&gt;if&lt;/font&gt;&lt;/span&gt; (&lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;.Count                 &amp;gt; 0)&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;                 {&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;      &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;List&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&amp;gt; lines = &lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;                 &lt;span&gt;&lt;font color="#2b91af"&gt;List&lt;/font&gt;&lt;/span&gt;&amp;lt;&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&amp;gt;();&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;      &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;foreach&lt;/font&gt;&lt;/span&gt; (&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt; key &lt;span&gt;&lt;font color="#0000ff"&gt;in&lt;/font&gt;&lt;/span&gt;                 &lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;.Keys) lines.Add(key + _separator                 + &lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;[key]);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;      &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;File&lt;/font&gt;&lt;/span&gt;.WriteAllLines(&lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;.FileName, lines.ToArray(), _encoding);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;                 }&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;    &lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 8pt;"&gt;                 &lt;span&gt;&lt;font color="#0000ff"&gt;else&lt;/font&gt;&lt;/span&gt; &lt;span&gt;&lt;font color="#2b91af"&gt;File&lt;/font&gt;&lt;/span&gt;.WriteAllText(&lt;span&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;&lt;/span&gt;.FileName, &lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;.Empty,                 _encoding);&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;font face="Courier New"&gt;&lt;span lang="EN-US" style="font-family: courier new;"&gt;&lt;span&gt;             &lt;font style="font-size: 8pt;"&gt;  &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: courier new;"&gt;                 &lt;font style="font-size: 8pt;"&gt;}&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 0pt; line-height: normal;"&gt;         &lt;span style="font-family: courier new;"&gt;&lt;font face="Courier New"&gt;&lt;font style="font-size: 8pt;"&gt;             }&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;         &lt;br /&gt;
Osservazioni e consigli sono ovviamente ben accetti!!! :)&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:2ce3b06f-246c-46ed-94d5-aad11e74b7fb" style="margin: 0px; padding: 0px; float: none; display: inline;"&gt;         Tag di Technorati: &lt;a rel="tag" href="http://technorati.com/tags/Dictionary"&gt;Dictionary&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/C%23"&gt;C#&lt;/a&gt;&lt;/div&gt;
&lt;/span&gt;&lt;img src="http://blogs.ugidotnet.org/dsantarelli/aggbug/99388.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org/dsantarelli/archive/2010/10/23/dictionary-persistenti.aspx</guid>
            <pubDate>Sat, 23 Oct 2010 00:37:20 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/dsantarelli/archive/2010/10/23/dictionary-persistenti.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/dsantarelli/comments/commentRss/99388.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/dsantarelli/services/trackbacks/99388.aspx</trackback:ping>
        </item>
        <item>
            <title>LINQ to CSV</title>
            <link>http://blogs.ugidotnet.org/dsantarelli/archive/2009/04/27/linq-to-csv.aspx</link>
            <description>&lt;p&gt;Veramente utile!!! :D&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;&lt;a href="http://www.codeproject.com/KB/linq/LINQtoCSV.aspx"&gt;http://www.codeproject.com/KB/linq/LINQtoCSV.aspx&lt;/a&gt;&lt;/font&gt;&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:29498a2b-252a-48c5-9659-365f84b2e2ea" style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;Technorati Tag: &lt;a rel="tag" href="http://technorati.com/tags/LINQ"&gt;LINQ&lt;/a&gt;,&lt;a rel="tag" href="http://technorati.com/tags/CSV"&gt;CSV&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org/dsantarelli/aggbug/96054.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org/dsantarelli/archive/2009/04/27/linq-to-csv.aspx</guid>
            <pubDate>Mon, 27 Apr 2009 17:35:37 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/dsantarelli/archive/2009/04/27/linq-to-csv.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/dsantarelli/comments/commentRss/96054.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/dsantarelli/services/trackbacks/96054.aspx</trackback:ping>
        </item>
    </channel>
</rss>