<?xml version="1.0" encoding="Windows-1252"?><feed version="0.3" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns="http://purl.org/atom/ns#" xml:lang="it-it"><title>Ricciolo.NET - Il blog di Cristian "Ricciolo" Civera</title><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/" /><tagline type="text/html">Ricciolo.NET - Il blog di Cristian &quot;Ricciolo&quot; Civera</tagline><id>http://blogs.aspitalia.com/ricciolo/</id><generator url="http://feed.aspitalia.com/" version="ASPItalia.com">feed.ASPItalia.com 'Weyoh' 4.8.715</generator><author><name>Ricciolo.NET - Il blog di Cristian &quot;Ricciolo&quot; Civera</name><url>http://blogs.aspitalia.com/ricciolo/</url></author><modified>2008-07-19T09:20:01+01:00</modified><entry><title>Reflection: migliorare le performance</title><id>http://blogs.aspitalia.com/ricciolo/post2332/Reflection-Migliorare-Performance.aspx</id><created>2008-07-17T22:34:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2332' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;La reflection &#232; quello strumento che permette di interrogare a runtime i metadati di un assembly, analizzare i tipi, i membri ed invocare dinamicamente metodi, propriet&#224; ed eventi. Il namespace &lt;strong&gt;System.Reflection&lt;/strong&gt; c'&#232; dal .NET Framework 1.0 e l'importanza di questo strumento si &#232; fatta sempre pi&#249; sentire, da una parte perch&#233; il framework &#232; sempre pi&#249; configurabile, dall'altra perch&#233; framework come &lt;strong&gt;NHibernate&lt;/strong&gt;, &lt;strong&gt;Linq to SQL&lt;/strong&gt; o &lt;strong&gt;Entity Framework&lt;/strong&gt; lo pongono al centro di una questione importante: le performance.&lt;/p&gt;&lt;p&gt;Infatti la reflection &#232; lenta. Tanto per dare un'idea con un semplice esempio, se dobbiamo creare un'istanza di una classe possiamo farlo chiamando il costruttore nel canonico modo oppure via reflection:&lt;/p&gt;&lt;p&gt;&lt;code&gt;for (int x = 0; x &amp;lt; max; x++)&lt;br /&gt;&#160; &#160; p = new Product();&lt;/p&gt;&lt;p&gt;Type t = typeof(Product);&lt;br /&gt;for (int x = 0; x &amp;lt; max; x++)&lt;br /&gt;&#160; &#160; p = Activator.CreateInstance(t);&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Sulla mia macchina, con 10milioni di iterazioni ottengo questi tempi:&lt;/p&gt;&lt;p&gt;&lt;code&gt;00:00:00.1892963&lt;br /&gt;00:00:01.8751132&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Ci mette ben 10 volte di pi&#249;. Per non parlare di come impostare le propriet&#224;:&lt;/p&gt;&lt;p&gt;&lt;code&gt;for (int x = 0; x &amp;lt; max; x++)&lt;br /&gt;&#160;&#160;&#160; p.Description = &amp;quot;ciao&amp;quot;;&lt;/p&gt;&lt;p&gt;PropertyInfo pi = typeof(Product).GetProperty(&amp;quot;Description&amp;quot;, BindingFlags.Public | BindingFlags.Instance);&lt;br /&gt;for (int x = 0; x &amp;lt; max; x++)&lt;br /&gt;&#160;&#160;&#160; pi.SetValue(p, &amp;quot;ciao&amp;quot;, null);&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Escludendo i tempi di ricerca della propriet&#224; con il metodo &lt;strong&gt;GetProperty&lt;/strong&gt;, i dati sono:&lt;/p&gt;&lt;p&gt;&lt;code&gt;00:00:00.1141661&lt;br /&gt;00:00:16.4958957&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Ovviamente questi sono dati indicativi ed &#232; ovvio che il confronto con il codice compilato &#232; ingiusto. Con la reflection abbiamo pi&#249; dinamicit&#224; sui tipi e possiamo creare strumenti come gli ORM citati prima.&lt;/p&gt;&lt;p&gt;Come si possono quindi aumentare le performance? Una possibilit&#224; &#232; quella di generare dinamicamente codice specifico per quel tipo e per certi membri.&#160;Infatti all'interno del namespace &lt;strong&gt;System.Reflection.Emit&lt;/strong&gt; c'&#232; tutto quello che serve per emettere IL al volo godendo delle stesse performance del codice compilato.&lt;br /&gt;Una delle accuse che si fanno a NHibernate o LINQ to SQL &#232; che sono lenti per via della reflection. In realt&#224;, sia il primo (dalla versione v2) che il secondo, tolto il lavoro che fanno inizialmente di analisi delle classi e dei mapping, non usano reflection, ma a regime istanziano e impostano campi e propriet&#224; con IL generato ad hoc. L'overhead semmai risiede nella gestione dei delegate e&#160;nel lavoro di mapping. In fondo se si pretende di lavorare indipendentemente dal database e&#160;instanziare tipi dinamicamente, non si pu&#242; neanche pretendere di non pagare qualcosa per questa ulteriore stratificazione.&lt;/p&gt;&lt;p&gt;Comunque non &#232; delle implementazioni degli ORM che mi interessa parlare, ma bens&#236; di come generare codice IL. Lo mostrer&#242; nel prossimo post dove far&#242; vedere alcuni extension method che usano la System.Reflection.Emit e la classe &lt;strong&gt;LambaExpression&lt;/strong&gt; per velocizzare le operazioni di reflection.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework/&quot; rel=&quot;tag&quot;&gt;.NET Framework&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_2.0/&quot; rel=&quot;tag&quot;&gt;.NET Framework 2.0&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.0/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.0&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.5/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.5&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2332/Reflection-Migliorare-Performance.aspx"/><issued>2008-07-17T22:34:00+01:00</issued><modified>2008-07-17T22:34:00+01:00</modified><slash:comments>0</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2332/Reflection-Migliorare-Performance.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2332.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2332</trackback:ping></entry><entry><title>Riutilizzare porzioni di espressioni LINQ</title><id>http://blogs.aspitalia.com/ricciolo/post2306/Riutilizzare-Porzioni-Espressioni-LINQ.aspx</id><created>2008-07-04T05:31:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2306' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Se anche voi usate in alcuni progetti &lt;strong&gt;LINQ to SQL&lt;/strong&gt; come &lt;strong&gt;DAL&lt;/strong&gt;, vi troverete un domain model e le classi create tramite il &lt;strong&gt;DBML&lt;/strong&gt;. Questo perch&#233; le prime vengono usate nello strato di presentazione e in quello business, mentre le seconde utilizzate all'interno del DAL realizzato con LINQ to SQL.&lt;br /&gt;Di conseguenza ci ritroviamo a dover mappare le due entit&#224; in modi pi&#249; o meno complessi. Poniamo di avere la classe Customer di LINQ to SQL e quella del domain model (per semplificare con mapping 1:1):&lt;/p&gt;&lt;p&gt;&lt;code&gt;public class CustomerL2S&lt;br /&gt;{&lt;br /&gt;   public int ID { get; set; }&lt;br /&gt;   public string Description { get; set; }&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;public class Customer&lt;br /&gt;{&lt;br /&gt;   public int ID { get; set; }&lt;br /&gt;   public string Description { get; set; }&lt;br /&gt;}&lt;/code&gt;&lt;/p&gt;&lt;p&gt;In un ipotetico metodo GetSingle che dato l'ID ti d&#224; l'entit&#224;, scriviamo qualcosa del genere:&lt;/p&gt;&lt;p&gt;&lt;code&gt;var customer = from c in customers&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;where c.ID == 1&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;select new Customer&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ID = c.ID,&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Description = c.Description&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;};&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Poi magari un metodo di List restituisce tutti i Customer, senza filtrarli e purtroppo ci tocca duplicare l'intera query, compreso tutto il mapping, senza la clausola where. Potremmo essere tentati di fare una funzione, cos&#236;:&lt;/p&gt;&lt;p&gt;&lt;code&gt;var customer = from c in customers&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;where c.ID == 1&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;select GetCustomer(c);&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Purtroppo questa tecnica non funziona, perch&#233; passiamo una funzione managed al motore di LINQ to SQL che non pu&#242; passarla a SQL Server. Il problema non sta nella funzione, ma in ci&#242; che essa fa. Infatti la soluzione sta nel lavorare sempre a livello di expression tree. Potremmo infatti creare un extension method (solo per comodit&#224; nella chiamata) specifico per il Customer che effettua il mapping che ci permetta di riutilizzarlo pi&#249; volte:&lt;/p&gt;&lt;p&gt;&lt;code&gt;public static class Extentions&lt;br /&gt;{&lt;br /&gt;   public static IQueryable&amp;lt;Customer&amp;gt; SelectToCustomer(this IQueryable&amp;lt;CustomerL2S&amp;gt; source)&lt;br /&gt;   {&lt;br /&gt; &amp;nbsp; &amp;nbsp;   return source.Select(c =&amp;gt; new Customer&lt;br /&gt; &amp;nbsp; &amp;nbsp;   {&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;   ID = c.ID,&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;   Description = c.Description&lt;br /&gt; &amp;nbsp; &amp;nbsp;   });&lt;br /&gt;   }&lt;br /&gt;}&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Nella funzione accettiamo un IQueryable specifico per l'entit&#224; CustomerL2S e sfruttando l'extension method select effettuamo il mapping, ma sempre a livello di espressione, consentendola di portarla su SQL Server. L'utilizzo poi &#232; semplice:&lt;/p&gt;&lt;p&gt;&lt;code&gt;var customer = (from c in customers&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;   where c.ID == 1&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;   select c).SelectToCustomer();&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Il doppio select &#232; d'obbligo per via della query syntax, ma non &#232; un problema poich&#233; la query SQL generata &#232; corretta.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework/&quot; rel=&quot;tag&quot;&gt;.NET Framework&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.5/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.5&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/LINQ/&quot; rel=&quot;tag&quot;&gt;LINQ&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/LINQ_to_SQL/&quot; rel=&quot;tag&quot;&gt;LINQ to SQL&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2306/Riutilizzare-Porzioni-Espressioni-LINQ.aspx"/><issued>2008-07-04T05:31:00+01:00</issued><modified>2008-07-04T05:31:00+01:00</modified><slash:comments>0</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2306/Riutilizzare-Porzioni-Espressioni-LINQ.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2306.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2306</trackback:ping></entry><entry><title>LINQ to SQL: Chiamare extension method non implementati</title><id>http://blogs.aspitalia.com/ricciolo/post2302/LINQ-SQL-Chiamare-Extension-Method-Implementati.aspx</id><created>2008-06-30T18:31:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2302' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Credo che qualcuno si sia gi&#224; imbatutto in un problema dovuto ad una&#160;query&#160;&lt;strong&gt;LINQ to SQL&lt;/strong&gt; simile a questa:&lt;/p&gt;&lt;p&gt;&lt;code&gt;bool MiaFunzione(Customer c)&lt;br /&gt;{&lt;br /&gt;&#160;&#160;&#160; return true;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var customer = from c in dc.Customers&lt;br /&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where MiaFunzione(c)&lt;br /&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select c;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Se lo eseguiamo otterremo un exception perch&#233; MiaFunzione &#232; un metodo managed e non pu&#242; essere valutato tramite una query &lt;strong&gt;SQL&lt;/strong&gt;. L'esempio pu&#242; sembrare palese, ma in realt&#224; questo problema&#160;c'&#232; anche con extesion method come Contains o tutti quelli che accettano un &lt;strong&gt;IEqualityComparer&lt;/strong&gt;, non portabile sul SQL Server.&lt;/p&gt;&lt;p&gt;Poich&#233; quando chiamiamo un extension method il compilatore individua il metodo che come argomento vuole il tipo pi&#249; vicino alla variabile, quando interroghiamo dc.Customers, la cui propriet&#224; &#232; di tipo &lt;strong&gt;Table&amp;lt;T&amp;gt;&lt;/strong&gt; che a sua volta implementa &lt;strong&gt;IQueryable&amp;lt;T&amp;gt;,&lt;/strong&gt; andiamo a chiamare i metodi contenuti nella classe &lt;strong&gt;System.Linq.Queryable&lt;/strong&gt; i quali lavorano sull'espressione, per poi essere valuta, trasformata in query SQL ed eseguita,&#160;all'effettivo consumo dell'enumeratore.&lt;br /&gt;Se per&#242; il tipo &#232; &lt;strong&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/strong&gt; andiamo a chiamare i metodi della classe &lt;strong&gt;System.Linq.Enumerable&lt;/strong&gt;, non lavorando pi&#249; sull'espressione, ma aggiungendo nuovi iteratori che valuteranno T ad ogni ciclo.&lt;/p&gt;&lt;p&gt;Di conseguenza, per risolvere i problema basta effettuare un downcast su IEnumerable&amp;lt;T&amp;gt; o meglio ancora l'extesion method &lt;strong&gt;AsEnumerable&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;code&gt;var customer = from c in dc.Customers.AsEnumerable()&lt;br /&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; where MiaFunzione(c)&lt;br /&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select c;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Attenzione per&#242;, cos&#236; facendo l'extension method Where consuma l'intero dc.Customers ottenuto da SQL Server, di conseguenza viene scaricata l'intera tabella dal DB per poi essere filtrata con LINQ to Object. Il alcuni casi potrebbe andare bene, in altri no; basta saperlo.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework/&quot; rel=&quot;tag&quot;&gt;.NET Framework&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.5/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.5&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/LINQ/&quot; rel=&quot;tag&quot;&gt;LINQ&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/LINQ_to_SQL/&quot; rel=&quot;tag&quot;&gt;LINQ to SQL&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2302/LINQ-SQL-Chiamare-Extension-Method-Implementati.aspx"/><issued>2008-06-30T18:31:00+01:00</issued><modified>2008-06-30T18:31:00+01:00</modified><slash:comments>0</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2302/LINQ-SQL-Chiamare-Extension-Method-Implementati.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2302.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2302</trackback:ping></entry><entry><title>Extension method ricorsivo per LINQ</title><id>http://blogs.aspitalia.com/ricciolo/post2298/Extension-Method-Ricorsivo-LINQ.aspx</id><created>2008-06-30T09:12:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2298' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Ultimamente sto giocando parecchio con LINQ e trovo incredibile come possa cambiare il modo di scrivere parti di codice: tutto diventa pi&#249; leggibile e si ha subito l'idea di cosa una query faccia.&lt;/p&gt;&lt;p&gt;Oggi dovevo sfogliare tutte le sezioni di configurazioni e per ognuna chiamare il metodo ProtectSection per criptarla. Siccome ogni gruppo di configurazione ha delle sezioni e a sua volta dei sotto gruppi di configurazione, dovevo fare una funzione da richiamare in modo ricorsivo per ogni gruppo, ma non mi piaceva. La domanda che ormai mi pongo &#232;: si pu&#242; fare in LINQ? In questo caso no o almeno io non ho trovato un extension method o una combinazione di essi che facesse al caso mio. Perci&#242; ne ho creato uno mio generico, per rendere flat una struttura ad albero:&lt;/p&gt;&lt;p&gt;&lt;code&gt;public static class Extensions&lt;br /&gt;{&lt;br /&gt;&#160;&#160;public static IEnumerable&lt;t /&gt; ToFlat&lt;t /&gt;(this IEnumerable&lt;t /&gt; source, Func&amp;lt;T, IEnumerable&amp;lt;T&amp;gt;&lt;t, /&gt;&amp;gt; childPredicate)&lt;br /&gt;&#160;&#160;{&lt;br /&gt;&#160;&#160;&#160;&#160;foreach (T t in source)&lt;br /&gt;&#160;&#160;&#160;&#160;{&lt;br /&gt;&#160;&#160;&#160;&#160;&#160;&#160;yield return t;&lt;/p&gt;&lt;p&gt;&#160;&#160;&#160;&#160;&#160;&#160;IEnumerable&lt;t /&gt; children = childPredicate(t);&lt;br /&gt;&#160;&#160;&#160;&#160;&#160;&#160;foreach (T child in ToFlat(children, childPredicate))&lt;br /&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;yield return child;&lt;br /&gt;&#160;&#160;&#160;&#160;}&lt;br /&gt;&#160;&#160;}&lt;br /&gt;}&lt;/code&gt;&lt;/p&gt;&lt;p&gt;In pratica, prende una lista e la sfoglia restituendo ogni elemento della lista stessa. Poi attraverso un predicato ottiene i figli di ogni elemento e per ognuno chiama ricorsivamente la funzione. In questo modo si ottiene un enumeratore piatto che sfoglia tutti gli elementi di una struttura ad al albero.&lt;/p&gt;&lt;p&gt;L'utilizzo poi &#232; banale. Per esempio per sfogliare tutti i controlli di una pagina (il cast serve perch&#233; ControlsCollection non implementa IEnumerable&lt;t /&gt;):&lt;/p&gt;&lt;p&gt;&lt;code&gt;var allControls = this.Controls.Cast&lt;control /&gt;().ToFlat(c =&amp;gt; c.Controls)&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Semplice ed efficace, vero?&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework/&quot; rel=&quot;tag&quot;&gt;.NET Framework&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.5/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.5&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/LINQ/&quot; rel=&quot;tag&quot;&gt;LINQ&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2298/Extension-Method-Ricorsivo-LINQ.aspx"/><issued>2008-06-30T09:12:00+01:00</issued><modified>2008-06-30T09:12:00+01:00</modified><slash:comments>0</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2298/Extension-Method-Ricorsivo-LINQ.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2298.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2298</trackback:ping></entry><entry><title>Uso improprio dei generics</title><id>http://blogs.aspitalia.com/ricciolo/post2301/Uso-Improprio-Generics.aspx</id><created>2008-06-28T17:56:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2301' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;I generics sono tanto belli bellini. Senza di essi non esisterebbe &lt;strong&gt;LINQ&lt;/strong&gt;,&#160;gli extension method non avrebbero trovato cos&#236; ampio spazio e non potremmo scrivere classi generiche utilizzabili per pi&#249; tipi.&lt;/p&gt;&lt;p&gt;Ci sono alcune pratiche per&#242; che&#160;mi capitano di vedere e io non ritengo corrette. Per esempio capita di vedere metodi che accettano un tipo generico ed effettuano un cast al loro interno, celandolo al chiamante:&lt;/p&gt;&lt;p&gt;&lt;code&gt;public static T GetValue&amp;lt;T&amp;gt;()&lt;br /&gt;{&lt;br /&gt;&#160;&#160;&#160; object obj = ....;&lt;br /&gt;&#160;&#160;&#160; return (T)obj;&lt;br /&gt;}&lt;/code&gt;&lt;/p&gt;&lt;p&gt;L'esempio &#232; banale, ma sufficiente per illustrare il mio dubbio. I generics son nati per tipizzare e migliorare anche in performance (evitano cast e box/unbox). Nel passato si usava un ArrayList e la cosa principalmente brutta era non avere una tipizzazione e si rischiava di cadere in &lt;strong&gt;InvalidCastException&lt;/strong&gt;. Con i generics questo problema &#232; stato risolto. Ci&#242; che non mi piace del codice precedente &#232; che celiamo al chiamante il fatto che io faccio un cast e per chi usa questo metodo sembra tutto sicuro e tipizzato.&lt;br /&gt;In &lt;strong&gt;LINQ to DataSet&lt;/strong&gt; hanno messo l'extesion method &lt;strong&gt;Field&amp;lt;T&amp;gt;&lt;/strong&gt; che data la colonna ti restituisce il valore tipizzato, cos&#236;:&lt;/p&gt;&lt;p&gt;&lt;code&gt;int c = row.Field&amp;lt;int&amp;gt;(&amp;quot;colonna&amp;quot;)&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Qual'&#232; la differenza rispetto a quest'altro codice?&lt;/p&gt;&lt;p&gt;&lt;code&gt;int c = (int)row[&amp;quot;colonna&amp;quot;]&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Di fatto nessuna. Entrambi sono potenzialmente vittime di un InvalidCastException, solo che il primo codice &#232; stilisticamente pi&#249; bello da vedere. Non trovate? Ormai avere un cast nel codice &#232; come avere qualcosa di sporco e infatti nella maggior parte dei casi secondo me &#232; cos&#236;. Con l'extension method generic hanno reso pi&#249; bello il codice, ma di fatto il problema resta.&lt;br /&gt;E' vero che nella documentazione c'&#232; giustamente scritto che tra le probabili eccezioni c'&#232; tale eccezione, ma a questo punto allora mi domando: perch&#233; implementare un metodo del genere?&lt;/p&gt;&lt;p&gt;Viceversa trovo molto bello l'uso dei metodi generic per effettuare downcast. Per esempio:&lt;/p&gt;&lt;p&gt;&lt;code&gt;public static IEnumerable&amp;lt;TSource&amp;gt; AsEnumerable&amp;lt;TSource&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source)&lt;br /&gt;{&lt;br /&gt;&#160;&#160;&#160; return source;&lt;br /&gt;}&lt;/code&gt;&lt;/p&gt;&lt;p&gt;In questo caso non viene coinvolto nessun cast, cosa che dovrei usare (seppure in modo sicuro) se non avessi questo metodo, ma semplicemente diciamo al compilatore su che tipo riferirsi se poi eventualmente chiamiamo altri metodi.&lt;/p&gt;&lt;p&gt;Ok, ci sono problemi ben pi&#249; seri nella vita, ma comunque rendo pubblica questa mia riflessione.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework/&quot; rel=&quot;tag&quot;&gt;.NET Framework&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.0/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.0&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.5/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.5&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/LINQ/&quot; rel=&quot;tag&quot;&gt;LINQ&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2301/Uso-Improprio-Generics.aspx"/><issued>2008-06-28T17:56:00+01:00</issued><modified>2008-06-28T17:56:00+01:00</modified><slash:comments>1</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2301/Uso-Improprio-Generics.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2301.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2301</trackback:ping></entry><entry><title>Le novit&amp;#224; di WPF 3.5 nel service pack 1</title><id>http://blogs.aspitalia.com/ricciolo/post2284/Novita-WPF-3.5-Service-Pack.aspx</id><created>2008-05-13T19:56:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2284' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Come &lt;a href=&quot;http://www.aspitalia.com/focuson/1038/Beta-Pubblica-SP1-.NET-Framework-3.5-2008.aspx&quot;&gt;sappiamo&lt;/a&gt; &#232; in corso lo sviluppo del service pack 1 del &lt;strong&gt;.NET Framework 3.5&lt;/strong&gt; e anche WPF non immune da nuove funzionalit&#224;.&lt;/p&gt;&lt;p&gt;Cominciamo dai controlli che si arricchiscono dei nuovi &lt;strong&gt;DataGrid&lt;/strong&gt;, &lt;strong&gt;WebBrowser&lt;/strong&gt; e in futuro anche di &lt;strong&gt;Office Ribbon&lt;/strong&gt;. Il primo, fortemente richiesto, supporta&#160;modifiche in place&#160;transazionali, ordinamento, multi selezione, validazione e la virtualizzazione delle righe e delle colonne&#160;come gi&#224; avviene, per esempio,&#160;per la ListBox. Il WebBrowser invece, in alternativa al Frame, permette di accedere al DOM della pagina, avere un maggior controllo del componenti IE&#160;e&#160;consente di&#160;incorporare anche applicazioni in &lt;strong&gt;Silverlight&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Ai nuovi controlli si aggiungono piccoli ritocchi:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;supporto StringFormat nelle espressioni di &lt;strong&gt;Binding&lt;/strong&gt;;&lt;/li&gt;&lt;li&gt;template per righe alternate negli &lt;strong&gt;ItemsControl&lt;/strong&gt;;&lt;/li&gt;&lt;li&gt;la virtualizzazione delle righe per gli ItemsControl pu&#242; ora reciclare (attached property VirtualizationMode)&#160;gli elementi non pi&#249; visibile e permettere lo scrolling e relativa creazione degli elementi&#160;solo quando l'utente rilascia il mouse (attached property IsDeferredScrollingEnabled), cos&#236; da risparmiare memoria. Anche la &lt;strong&gt;TreeView&lt;/strong&gt; supporta ora la virtualizzazione degli elementi.&#160;Per maggiori informazioni sull'attuale funzionamento &#232; disponibile &lt;a href=&quot;http://www.winfxitalia.com/articoli/presentation-foundation/controlli-elenco-WPF.aspx&quot;&gt;questo articolo&lt;/a&gt;;&lt;/li&gt;&lt;li&gt;nuova interfaccia &lt;strong&gt;IEditableCollectionView&lt;/strong&gt; per intervenire tramite viste sulle sorgenti dati;&lt;/li&gt;&lt;li&gt;supporto al binding con sorgenti Linq To Sql e Linq To Entities migliorando inoltre le performance con &lt;strong&gt;IEnumerable&lt;/strong&gt;;&lt;/li&gt;&lt;li&gt;miglioramenti di performance nel rendering di testo, nella grafica 2D e nella classe &lt;strong&gt;WriteableBitmap&lt;/strong&gt;;&lt;/li&gt;&lt;li&gt;alla propriet&#224; &lt;strong&gt;BitmapEffect&lt;/strong&gt; si affianca Effect che a differenza dell'altra permette di utilizzare effetti come blur e shadow mediante l'accelarazione grafica e sfruttando le capacit&#224; di pixel shader delle GPU, rendendolo di fatto di gran lunga pi&#249; performance rispetto all'elaborazioni bitmap basate su CPU;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;A tutto questo non mancano miglioramenti all'ambiente di sviluppo in &lt;strong&gt;Visual Studio 2008&lt;/strong&gt;, costituiti da un completo supporto agli eventi e agli style, al refactoring e references&#160;degli elementi, ad una migliore segnalazione&#160;dei problemi&#160;in caso di eventuali errori&#160;a runtime&#160;nel markup, non rilevati in fase di compilazione.&lt;/p&gt;&lt;p&gt;Per ultimo vi sono novit&#224; sul fronte client (quindi anche WinForms) e al deployment degli applicativi. E' prevista una nuova modalit&#224; &amp;quot;&lt;strong&gt;Client profile&lt;/strong&gt;&amp;quot; che consente di distribuire l'applicativo richiedendo solo un sotto insieme degli assembly contenuti nel framework escludendo quelli che trovano utilit&#224; solo in applicazione server, come per esempio la parte di ASP.NET, riducendo il setup a circa 20MB (rispetto a 270MB totali).&lt;br /&gt;Ad esso si unisce un piccolo bootstrapper, compatibile con &lt;strong&gt;ClickOnce&lt;/strong&gt; (interfaccia ora&#160; personalizzabile), che si occupa di installare l'intero .NET Framework 3.5 o se richiesto solo il sotto insieme client e in un secondo momento, se richiesto da un'ulteriore applicazione, di installare il restante Framework.&#160;&#160;Anche Visual Studio 2008 supporta questa modalit&#224; e presenta degli errori in fase di compilazione nel caso dovessimo usare assembly non presenti nel Framework ridotto.&lt;/p&gt;&lt;p&gt;Non ci sono eclatanti novit&#224; a dimostrazione del fatto che gi&#224; WPF nella sua prima versione era gi&#224; un ottimo framework, ma devo dire che mi soddisfano. Forse resta l'ambiente di sviluppo ancora un po' indietro e manca ancora di molte funzionalit&#224;, ma a piccoli passi forse ce la faremo :-)&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.0/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.0&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.5/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.5&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Visual_Studio/&quot; rel=&quot;tag&quot;&gt;Visual Studio&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Windows_Presentation_Foundation/&quot; rel=&quot;tag&quot;&gt;Windows Presentation Foundation&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/XAML/&quot; rel=&quot;tag&quot;&gt;XAML&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework/&quot; rel=&quot;tag&quot;&gt;.NET Framework&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2284/Novita-WPF-3.5-Service-Pack.aspx"/><issued>2008-05-13T19:56:00+01:00</issued><modified>2008-05-13T19:56:00+01:00</modified><slash:comments>0</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2284/Novita-WPF-3.5-Service-Pack.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2284.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2284</trackback:ping></entry><entry><title>Styles Explorer: decompilatore BAML</title><id>http://blogs.aspitalia.com/ricciolo/post2263/Styles-Explorer-Decompilatore-BAML.aspx</id><created>2008-04-04T23:57:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2263' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Vi ricordate quando vi &lt;a href=&quot;http://blogs.aspitalia.com/ricciolo/post2124/Come-Fatto-Formato-BAML-WPF.aspx&quot;&gt;parlai&lt;/a&gt; di come viene compilato lo &lt;strong&gt;XAML&lt;/strong&gt; e quale struttura ha? Beh &#232; un po' che avevo pi&#249; o meno pronta quella classe e mancava qualcosa per usarla a dovere. Portando avanti a singhiozzo il progetto, finalmente posso farvi vedere qualcosa di &lt;strong&gt;Styles Explorer&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;E' uno strumento che ti permette di aprire qualsiasi DLL, enumerare le risorse &lt;strong&gt;BAML&lt;/strong&gt; che contiene e decompilare (se ce la fa) fornendo l'XML. E' principalmente improntato sui &lt;strong&gt;ResourceDictionary&lt;/strong&gt;, perci&#242; &#232; in grado di fornire un'anteprima di un oggetto o di uno style.&lt;/p&gt;&lt;p&gt;Siccome i tempi cambiano, invece degli screenshot vi metto un bel filmato&lt;/p&gt;&lt;embed pluginspage=&quot;http://macromedia.com/go/getflashplayer&quot; src=&quot;http://images.video.msn.com/flash/soapbox1_1.swf&quot; width=&quot;432&quot; height=&quot;364&quot; type=&quot;application/x-shockwave-flash&quot; flashvars=&quot;c=v&amp;amp;v=184a6290-13ec-4aa3-8c37-51e85d430303&amp;amp;ifs=true&amp;amp;fr=msnvideo&amp;amp;mkt=en-US&amp;amp;brand=&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; base=&quot;http://images.video.msn.com&quot; quality=&quot;high&quot; /&gt;&lt;/embed /&gt;&lt;br /&gt;&lt;a title=&quot;Styles Explorer&quot; href=&quot;http://video.msn.com/video.aspx?vid=184a6290-13ec-4aa3-8c37-51e85d430303&quot; target=&quot;_new&quot;&gt;Video: Styles Explorer&lt;/a&gt;&lt;p&gt;Ovviamente il progetto &#232; ancora in corso e va migliorato, ma fino adesso mi son divertito a fare alcune cose carine, come usare pi&#249; AppDomain per isolare il caricamento degli assembly, o fare una nuova message pump solo per la preview cos&#236; da evitare problemi con il resto dell'applicazione.&lt;/p&gt;&lt;p&gt;Ah dimenticavo, potete installarlo da &lt;a href=&quot;http://ricciolo.lab.aspitalia.com/StylesExplorer/Ricciolo.StylesExplorer.application&quot;&gt;qua&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework/&quot; rel=&quot;tag&quot;&gt;.NET Framework&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.0/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.0&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.5/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.5&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Windows_Presentation_Foundation/&quot; rel=&quot;tag&quot;&gt;Windows Presentation Foundation&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/XAML/&quot; rel=&quot;tag&quot;&gt;XAML&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2263/Styles-Explorer-Decompilatore-BAML.aspx"/><issued>2008-04-04T23:57:00+01:00</issued><modified>2008-04-04T23:57:00+01:00</modified><slash:comments>2</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2263/Styles-Explorer-Decompilatore-BAML.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2263.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2263</trackback:ping></entry><entry><title>Le evoluzioni del Web che non capisco</title><id>http://blogs.aspitalia.com/ricciolo/post2256/Evoluzioni-Web-Capisco.aspx</id><created>2008-03-18T17:51:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2256' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Chi mi conosce sa che non sono un gran simpatizzante di &lt;strong&gt;AJAX&lt;/strong&gt; e riconoscendo che in effetti serve qualcosa di pi&#249; del buon vecchio HTML, trovo Silverlight decisamente una soluzione migliore. Ma non &#232; di questa moda che voglio parlare, ma bens&#236; di &lt;strong&gt;REST&lt;/strong&gt; e &lt;strong&gt;POX&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Con il primo termine si intende il voler sfruttare a pieno le capacit&#224; di &lt;strong&gt;HTTP&lt;/strong&gt;, mediante i suoi method, per ampliare l'applicazione web e fornire servizi aggiuntivi usufruibili al di fuori dell'HTML e della semplice navigazione. In pratica, siccome esistono i metodi &lt;strong&gt;GET&lt;/strong&gt;, &lt;strong&gt;POST&lt;/strong&gt;, &lt;strong&gt;PUT&lt;/strong&gt; e &lt;strong&gt;DELETE&lt;/strong&gt; si &#232; pensato di sfruttarli per eseguire le classiche operazioni CRUD, magari aggiugendo dei parametri nell'URI o nel contenuto della richiesta. Tutto questo ovviamente esiste da sempre, ma veniva marginalmente sfruttato e solo ora, e ben venga, siti come Amazon, Google, Live, ecc permettono di interrogare e di usufruire dei loro servizi mediante REST.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;POX&lt;/strong&gt; invece vuol dire Plain Old XML e in pratica vuol dire usare XML semplice senza fronzoli, da utilizzare nelle richieste o risposte REST.&lt;/p&gt;&lt;p&gt;Cosa non mi piace di tutto questo? Il fatto che si sta reinventando la ruota. Per esempio, chi espone operazioni REST si trova a dover fornire della documentazione per spiegare come chiamare le varie operazioni, come dev'essere passato l'XML e spesso in maniera superficiale, limitandosi ad un esempio di XML o ad un esempio di parametro in query string. Beh a tutto questo qualcuno ci aveva gi&#224; pensato e vedendo che non era sufficiente aveva pensato ai &lt;strong&gt;WebService&lt;/strong&gt;, a &lt;strong&gt;SOAP&lt;/strong&gt;, ai consorzi per renderli i pi&#249; interoperabili possibili. Per XML esistono gli schema &lt;strong&gt;XSD&lt;/strong&gt; che sono molto pi&#249; completi, mentre per conoscere quali operazioni espone un servizio c'&#232; &lt;strong&gt;WSDL&lt;/strong&gt; e &lt;strong&gt;WS-Metadata Exchange&lt;/strong&gt;. Senza contare che con framework come &lt;strong&gt;WCF&lt;/strong&gt; basta semplicemente fare un &amp;quot;Add Service reference&amp;quot; e ci si pu&#242; persino permettere di ignorare questi linguaggi e di esporre della documentazione aggiuntiva.&lt;/p&gt;&lt;p&gt;E' vero che non tutti fanno applicazioni enterprise ed usare WCF/WebService pu&#242; sembrare un carro armato per uccidere le mosche, ma sono del parere che alcune problematiche sono presenti anche in semplici siti web. Tra questi il gi&#224; citato, come chiamare un'operazione, ma anche quali errori mi pu&#242; eventualmente dare e come li gestisco. Poi man mano ci sono altri aspetti, come l'autenticazione, spesso affidata ad un token rilasciato da chi espone il servizio da inserire nella querystring, mentre in &lt;strong&gt;WS-*&lt;/strong&gt; tutto questo &#232; gi&#224; definito. Sono inoltre definiti come rendere le operazioni sicure, criptate, transazionali, come gestire le policy ed inviare file di grosse dimensioni. Ovviamente se tutto questo non serve basta non abilitarlo e l'XML resta contenuto, senza offenderlo chiamandolo POX :-).&lt;/p&gt;&lt;p&gt;E' per questo che storto un po' il naso e che il diffondersi di questi termini sia pi&#249; dovuto o ad ignoranza su certe tecnologie (almeno io so il loro nome :-) ) oppure ad una pigrizia nell'affrontarle ed impararle. Detto questo, sicuramente ci sono ambiti in cui una normale richiesta GET basta e avanza; l'importante che vengano valutate anche le altre strade e che non venga coniato qualche nuovo termine o nuova era del web.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/Silverlight/&quot; rel=&quot;tag&quot;&gt;Silverlight&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/XAML/&quot; rel=&quot;tag&quot;&gt;XAML&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2256/Evoluzioni-Web-Capisco.aspx"/><issued>2008-03-18T17:51:00+01:00</issued><modified>2008-03-18T17:51:00+01:00</modified><slash:comments>11</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2256/Evoluzioni-Web-Capisco.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2256.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2256</trackback:ping></entry><entry><title>Un'occhiata a Silverlight 2.0</title><id>http://blogs.aspitalia.com/ricciolo/post2248/Unocchiata-Silverlight-2.0.aspx</id><created>2008-03-08T17:29:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2248' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Come probabilmente &lt;a href=&quot;http://www.aspitalia.com/focuson/1027/Rilasciata-Ufficialmente-Versione-Beta1-Silverlight-2.0.aspx&quot;&gt;saprete&lt;/a&gt; &#232; stata rilasciata la beta &lt;strong&gt;Silverlight 2.0&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Ovviamente da fan di &lt;strong&gt;WPF&lt;/strong&gt; non ho resistito dal provarla subito. Sinceramente, delle scorse preview ero rimasto un po' deluso, poich&#233; conoscendo WPF mi rendevo conto di quante cose mancassero diventando cos&#236; frustrante giocarci. Beh invece con Silverlight 2.0 mi ritengo soddisfatto e entusiasta come un bambino che scarta i regali a Natale :-D&lt;/p&gt;&lt;p&gt;Per prima cosa il setup installa runtime, template per &lt;strong&gt;Visual Studio 2008&lt;/strong&gt; e SDK. Una parte del SDK &#232; rivolta al server e l'altra al client.&lt;/p&gt;&lt;p&gt;Lato server una nuova System.Web.Silverlight.dll contiene i controlli &lt;strong&gt;Silverlight&lt;/strong&gt; e &lt;strong&gt;MediaPlayer&lt;/strong&gt;. Il primo semplicemente crea il markup per istanziare il plugin, include il codice JavaScript e non &#232; pi&#249; necessario includere script esterni ecc. MediaPlayer &#232; un&#160;controllo pi&#249; evoluto che permette con due click di inserire un player di video con tanto di&#160;marcatori e capitoli basandosi su&#160;Silverlight. Il tutto completamente skinnabile, con&#160;una decina di skin gi&#224; presenti nel SDK. Molto maschio.&lt;/p&gt;&lt;p&gt;Lato client l'architettura &#232;&#160;rimasta invariata e il runtime, di soli 4,3MB,&#160;&#232;&#160;installato in %ProgramFiles%\Microsoft Silverlight\2.0.30226.2. Rispetto alla alpha abbiamo in pi&#249; System.ServiceModel (WCF quindi) con &lt;strong&gt;BasicHttpBinding&lt;/strong&gt;, supporto a &lt;strong&gt;REST&lt;/strong&gt; e&#160;&lt;strong&gt;JSON&lt;/strong&gt;. L'assembly System.Windows &#232; stato ampliato con altre classi base con niente popo di meno che: StackPanel, Grid, Border, TextBox, ItemsControl (i principali).&lt;/p&gt;&lt;p&gt;Incredibile, c'&#232; la classe &lt;strong&gt;Binding&lt;/strong&gt; con IValueConverter, BindingMode, Source, ma nessun altra tipologia di binding. In molti aspetti Silverlight assomiglia da fuori a WPF, ma dentro l'implementazione &#232; decisamente diversa, tendente al risparmio (non poteva essere diversamente). I controlli sono basati su &lt;strong&gt;DependencyProperty&lt;/strong&gt; (anche Attached Property), ma non &#232; presente&#160;nessun meccanismo di triggering o metadati aggiuntivi, mentre gli eventi invece sono quelli normali del CLR; quindi niente Attached Event, niente bubbling o tunneling ed eventi di preview.&lt;/p&gt;&lt;p&gt;I controlli si basano su &lt;strong&gt;Template&lt;/strong&gt; che vengono caricati tramite &lt;strong&gt;Style&lt;/strong&gt; avente come TargetType il tipo del controllo da personalizzare. Gli Style non hanno trigger, quindi nel metodo &lt;strong&gt;ApplyTemplate&lt;/strong&gt; ogni controllo cerca elementi nel template dal nome prefissato&#160;(es: RootElement), ne intercettono gli eventi e interagiscono in base a quest'ultimi. Questa tecnica esiste in modo identico anche in WPF, ma si usa raramente preferendo l'uso di trigger in modo da legare il meno possibile il codice al markup. Continuando con il paragone con WPF, niente Command, CollectionView e WeakEvent.&lt;/p&gt;&lt;p&gt;Tutto sommato quindi, le cose che si potevano implementare sono state copiate da WPF e questo non pu&#242; farmi che piacere&#160;:-), ma ovviamente per non esagerare nella dimensione degli assembly &#232; stato sacrificato qualcosa.&lt;/p&gt;&lt;p&gt;Da Visual Studio o Blend 2.5 possiamo creare un progetto Silverlight 2.0 e rispetto a prima, si sviluppa una specie di class library avente gi&#224; pronti i file App.xaml, che &#232; l'entry point, e un file Page.xaml: lo &lt;strong&gt;UserControl&lt;/strong&gt; principale. Ovviamente hanno il relativo code-behind dove possiamo scrivere in C# 3.0 o VB 9.&lt;br /&gt;Il risultato della compilazione &#232; un file &lt;strong&gt;.xap&lt;/strong&gt;, l'unico file da distribuire,&#160;che&#160;&#232; un file .zip contenente un file di metadati,&#160;i file che abbiamo incluso nel progetto con target Content e&#160;la nostra dll compilata. Quest'ultima contiene nelle risorse i file XAML, ma non compilati in &lt;strong&gt;BAML&lt;/strong&gt; (diversamente da WPF). Probabilmente questa scelta &#232; dovuta al fatto che l'ottimizzazione di caricamento del markup &#232; stata ritenuta sacrificabile, mentre la compressione &#232; gi&#224; ottenuta grazie allo ZIP.&lt;/p&gt;&lt;p&gt;Per ultimo una cosa inaspettata: nel progetto di Visual Studio troveremo referenziati altre dll che verranno poi incluse nel file xap. Queste&#160;normalmetne sono: &lt;strong&gt;System.Windows.Controls&lt;/strong&gt; e &lt;strong&gt;System.Windows.Controls.Extended&lt;/strong&gt;. Queste dll, pi&#249; altre,&#160;si trovano normalmente nella cartella del SDK (C:\Program Files\Microsoft SDKs\Silverlight\v2.0\Libraries\Client) e non sono incluse nel setup di Silverlight. Peccato che quest'altre 18 dll contengano: &lt;strong&gt;Ruby&lt;/strong&gt;, &lt;strong&gt;Python&lt;/strong&gt;, &lt;strong&gt;Managed JScript&lt;/strong&gt;, le classi Syndacation RSS/Atom di WCF, &lt;strong&gt;Linq To Xml&lt;/strong&gt;, controlli come Thumb (per il drag&amp;amp;drop), Button, CheckBox, ListBox, RadioButton, Slider, ScrollBar, ScrollViewer, ToolTip, ToggleButton, DataGrid, Calendar, DateTimePicker, GridSplitter, WatermarkedTextBox.&lt;/p&gt;&lt;p&gt;Prima di tutto stupisce che ci siano controlli che WPF non&#160;ha e sia Silverlight il primo ad implementarli, ma soprattutto ecco spiegato perch&#233; il runtime &#232; piccolo. Infatti tutte le altre dll le mandiamo noi all'utente inglobandole nel file xap. Cos&#236; l'installazione del plugin&#160;&#232; piccola,&#160;mentre l'utente navigando su pi&#249; siti si ritrova a scaricare solo le dll che effettivamente l'applicazione usa, con il rischio ovviamente di scaricare&#160;pi&#249; volte la stessa dll in pacchetti diversi. Furbini vero? :-D&lt;/p&gt;&lt;p&gt;Non l'ho ancora guardato benissimo, ma Silverlight cos&#236; mi piace decisamente e non ha rivali sul web. Se volete vederlo all'opera potete venire al &lt;a href=&quot;http://www.aspitalia.com/eventi/12/Real-Code-Launch-2008-Roma.aspx&quot;&gt;Real Code Launch&lt;/a&gt; che terremo a Roma. Dovete assolutamente venire; chi c'&#232;, c'&#232;, chi non c'&#232;... eh non c'&#232;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.0/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.0&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Microsoft_Expression/&quot; rel=&quot;tag&quot;&gt;Microsoft Expression&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Silverlight/&quot; rel=&quot;tag&quot;&gt;Silverlight&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Silverlight_-_animazioni/&quot; rel=&quot;tag&quot;&gt;Silverlight - animazioni&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Silverlight_2.0/&quot; rel=&quot;tag&quot;&gt;Silverlight 2.0&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Windows_Presentation_Foundation/&quot; rel=&quot;tag&quot;&gt;Windows Presentation Foundation&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/XAML/&quot; rel=&quot;tag&quot;&gt;XAML&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2248/Unocchiata-Silverlight-2.0.aspx"/><issued>2008-03-08T17:29:00+01:00</issued><modified>2008-03-08T17:29:00+01:00</modified><slash:comments>4</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2248/Unocchiata-Silverlight-2.0.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2248.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2248</trackback:ping></entry><entry><title>Ho aperto un nuovo blog</title><id>http://blogs.aspitalia.com/ricciolo/post2227/Aperto-Blog.aspx</id><created>2008-02-16T18:34:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2227' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Probabilmente vi domanderete perch&#233; abbia aperto un altro blog visto che a mala pena scrivo su questo. Semplice, per scrivere le mie esperienze in inglese. Quindi niente paura, le tematiche sono le stesse e&#160;se sfortunatamente leggete gi&#224; questo blog resterete sempre aggiornati:&#160;tutto quello che scriver&#242; in inglese verr&#224; scritto in italiano e forse anche viceversa.&lt;/p&gt;&lt;p&gt;Il blog si trova &lt;a href=&quot;http://blogs.windowsclient.net/RiccioloCristian/&quot;&gt;qua&lt;/a&gt;, aggregato sul sito di &lt;a href=&quot;http://www.windowsclient.net&quot; target=&quot;_blank&quot;&gt;windowsclient.net&lt;/a&gt;.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2227/Aperto-Blog.aspx"/><issued>2008-02-16T18:34:00+01:00</issued><modified>2008-02-16T18:34:00+01:00</modified><slash:comments>2</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2227/Aperto-Blog.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2227.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2227</trackback:ping></entry><entry><title>DirectShow e WPF: soluzione finale</title><id>http://blogs.aspitalia.com/ricciolo/post2213/DirectShow-WPF-Soluzione-Finale.aspx</id><created>2008-01-28T17:20:37+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2213' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;o quasi... :-) Nel precedente &lt;a href=&quot;http://blogs.aspitalia.com/ricciolo/post2210/sorgenti-custom-mediaelement-wpf.aspx&quot; onclick=&quot;blankUrl(this.href); return false;&quot;&gt;post&lt;/a&gt; ho parlato delle problematiche e possibili soluzioni per mostrare sorgenti video personalizzate in &lt;strong&gt;WPF&lt;/strong&gt;. Ho accennato ad una possibile terza soluzione e sebbene non perfetta la reputo la migliore.&lt;/p&gt; &lt;p&gt;Partiamo dal risultato. Nella figura sottostante potete ammirare un esemplare maschio homo sapiens sapiens:&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://blogs.aspitalia.com/img/ricciolo/directshowewpfsoluzionefinale_10201/camera_2.jpg&quot;&gt;&lt;img height=&quot;466&quot; alt=&quot;camera&quot; src=&quot;http://blogs.aspitalia.com/img/ricciolo/directshowewpfsoluzionefinale_10201/camera_thumb.jpg&quot; width=&quot;404&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;L'esempio &amp;#232; ottenuto usando come VisualBrush di un cubo 3D, un mio oggetto:&lt;/p&gt; &lt;p class=&quot;codebox&quot;&gt;&lt;code&gt;&amp;lt;ricciolo:WebcamElement Source=&amp;quot;webcam://WebcamElement/Video%20Camera&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Questa classe eredita da una classe base &lt;strong&gt;AdvancedMediaElement&lt;/strong&gt; (eredita dalla standard MediaElement) che offre le funzionalit&amp;#224; base per supportare qualsiasi grafo &lt;strong&gt;DirectShow&lt;/strong&gt;. Nello specifico, per l'intera applicazione uso una libreria Microsoft di nome &lt;a href=&quot;http://research.microsoft.com/sn/detours/&quot; onclick=&quot;blankUrl(this.href); return false;&quot;&gt;detours&lt;/a&gt; che permette di sovrascrivere le funzioni &lt;strong&gt;Win32&lt;/strong&gt; ed eventualmente chiamare la funzione originale. Per il mio scopo intercetto la chiamata a &lt;strong&gt;CoCreateInstance&lt;/strong&gt;, usata per instanziare gli oggetti &lt;strong&gt;COM&lt;/strong&gt;, e quando il MediaElement carica l'URL coercizzo il valore ad un file fisico vuoto creato al volo nella temp dir. &lt;strong&gt;Windows Media Player&lt;/strong&gt; carica DirectShow, crea il grafo e crea l'AsyncReader standard. Io che sono infame, mediante detours, restituisco un mio oggetto che implementa IAsyncReader e non presenta nessun pin. L'intelligent connect passa il nome del file &lt;strong&gt;IFileSourceFilter::Load&lt;/strong&gt; al mio filtro e poi si ferma, mentre quest'ultimo tramite callback notifica all'AdvancedMediaElement di caricare il grafo. Mediante l'associazione URI/istanza chiamo un metodo virtuale OnGraphLoad(IGraphBuilder graph) nella quale le varie implementazioni (nel mio caso WebcamElement) possono popolare il grafo con i fitri che vogliono lavorando via interop con l'ausilio di librerie tipo &lt;a href=&quot;http://directshownet.sourceforge.net/&quot; onclick=&quot;blankUrl(this.href); return false;&quot;&gt;DirectShowLib&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;La soluzione &amp;#232; in parte in C++ CLI, in parte in C#, &amp;#232; aperta ad altre implementazioni e non richiede nessuna registrazione di DLL (le detours sono inglobate nel mio assembly) o di protocol handler. L'unica nota dolente &amp;#232; quel finto file vuoto temporaneo che devo creare per costringere WMP ad usare DirectShow; se qualcune conosce quindi un'alternativa sar&amp;#242; ben contento di ascoltarla.&lt;/p&gt; &lt;p&gt;Presto sorgenti e applicazione di test nel lab&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2213/DirectShow-WPF-Soluzione-Finale.aspx"/><issued>2008-01-28T17:20:37+01:00</issued><modified>2008-01-28T17:20:37+01:00</modified><slash:comments>0</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2213/DirectShow-WPF-Soluzione-Finale.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2213.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2213</trackback:ping></entry><entry><title>Sorgenti custom per MediaElement di WPF</title><id>http://blogs.aspitalia.com/ricciolo/post2210/Sorgenti-Custom-MediaElement-WPF.aspx</id><created>2008-01-23T12:49:59+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2210' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;L'elemento &lt;strong&gt;MediaElement&lt;/strong&gt; &amp;#232; un gran bell'oggettino :-) Permette di mostrare e ascoltare video e audio, il tutto perfettamente integrato con WPF permettendoci di ridimensionarlo come ci pare, usarlo come brush, trasformarlo, applicare trasparenze, ecc...&lt;/p&gt; &lt;p&gt;L'unico problema &amp;#232; che al di l&amp;#224; di file su disco o uri http, non si pu&amp;#242; andare. Per esempio pu&amp;#242; essere utile usare come sorgente la webcam, un tuner TV o una fonte analogica esterna. Per ottenere ci&amp;#242; ci sono vari modi:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Usare l'elemento &lt;strong&gt;HwndSource&lt;/strong&gt; cos&amp;#236; da avere una finestra Win32. Tramite la propriet&amp;#224; Handle abbiamo il suo puntatore e possiamo quindi usare &lt;strong&gt;DirectShow&lt;/strong&gt; effettuando il rendering puntando la finestra con l'interfaccia &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms786984.aspx&quot; onclick=&quot;blankUrl(this.href); return false;&quot;&gt;IVideoWindow&lt;/a&gt;. Se vi interessa &amp;#232; disponibile &lt;a href=&quot;http://directshownet.sourceforge.net/&quot; onclick=&quot;blankUrl(this.href); return false;&quot;&gt;questo progetto&lt;/a&gt; pieno di classi interop per usare DirectShow in .NET. &lt;br /&gt;Questo approccio ha dei limiti dovuti al fatto che HwndSource &amp;#232; s&amp;#236; un elemento WPF, ma poich&amp;#233; contiene al suo interno una nuova finestra Win32 non permette di effettuare trasformazioni, trasparenze, ecc.&lt;/li&gt; &lt;li&gt;Costruire un protocol handler per un proprio schema (esempio webcam://qualcosa) che faccia uso di un source filter personalizzato per DirectShow. Questo &amp;#232; possibile perch&amp;#233; MediaElement utilizza al suo interno &lt;strong&gt;Windows Media Player&lt;/strong&gt; che a sua volta si basa su &lt;strong&gt;Windows Media Foundation&lt;/strong&gt; che a sua volta usa (se necessario) DirectShow.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Ho provato entrambi le modalit&amp;#224; e ovviamente la seconda &amp;#232; la migliore (esiste una terza che sto ancora sperimentando). Nella seconda ho scritto in C++ un source filter che implementa &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms785718.aspx&quot; onclick=&quot;blankUrl(this.href); return false;&quot;&gt;IFileSourceFilter&lt;/a&gt;, cos&amp;#236; da essere da essere chiamato per caricare il mio schema custom. Non entro troppo nei dettagli, ma &amp;#232; compito di WMP caricare il mio filtro e, una volta aggiunto al grafo DirectShow, renderizzare il pin video in uscita sfruttando l'&lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms786503(vs.85).aspx&quot; onclick=&quot;blankUrl(this.href); return false;&quot;&gt;Intelligent Connect&lt;/a&gt;. Questo sistema in pratica si mette a guardare i pin del filtro sorgente e prova le possibili combinazioni tra filtri di decodifica e di rendering fino a quando non riesce a mostrare il video e/o ad emettere il suono. In WPF il filtro sorgente quindi dipende dal protocol handler, mentre il rendering video viene effettuato mediante &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms694916(vs.85).aspx&quot; onclick=&quot;blankUrl(this.href); return false;&quot;&gt;Enhanced Video Renderer&lt;/a&gt;: un filtro nuovo e pi&amp;#249; evoluto che permette l'integrazione in WPF.&lt;/p&gt; &lt;p&gt;Nella mia prova ho usato il tipico filtro Ball presente nel SDK, costituito da un pin che restituisce uno stream video che mostra una palla rimbalzare. Una volta pronto il filtro, va poi registrato sia come dll, sia mappando lo schema custom al filtro. Possiamo poi usarlo sia in WMP che in GraphEdit (un tool per testare i filtri). Ecco uno screenshot:&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://blogs.aspitalia.com/img/ricciolo/sorgenticustompermediaelementdiwpf_9079/ball1.png&quot;&gt;&lt;img height=&quot;347&quot; alt=&quot;ball1&quot; src=&quot;http://blogs.aspitalia.com/img/ricciolo/sorgenticustompermediaelementdiwpf_9079/ball1_thumb.png&quot; width=&quot;400&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;A questo punto possiamo usare il filtro anche in WPF:&lt;/p&gt; &lt;p class=&quot;codebox&quot;&gt;&lt;code&gt;&amp;lt;MediaElement Source=&amp;quot;ball://test&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/p&gt; &lt;p&gt;E questo &amp;#232; il risultato che si ottiene applicandoci il tipico effetto riflesso, per far vedere che possiamo trattare il video come vogliamo:&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://blogs.aspitalia.com/img/ricciolo/sorgenticustompermediaelementdiwpf_9079/ball2.png&quot;&gt;&lt;img height=&quot;360&quot; alt=&quot;ball2&quot; src=&quot;http://blogs.aspitalia.com/img/ricciolo/sorgenticustompermediaelementdiwpf_9079/ball2_thumb.png&quot; width=&quot;250&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Quindi in teoria possiamo fare un pin che prenda lo stream da un grafo interno oppure possiamo fare un filtro senza pin, ma che sul metodo Load inserisce nel grafo un nuovo filtro sorgente (webcam, tuner ecc). Ci pensa poi l'intelligent connect ad ignorare il nostro filtro custom, proseguendo sull'altro da noi creato. Questa variante &amp;#232; stilisticamente meno carina, ma pi&amp;#249; semplice.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework/&quot; rel=&quot;tag&quot;&gt;.NET Framework&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.0/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.0&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.5/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.5&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/Windows_Presentation_Foundation/&quot; rel=&quot;tag&quot;&gt;Windows Presentation Foundation&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/XAML/&quot; rel=&quot;tag&quot;&gt;XAML&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2210/Sorgenti-Custom-MediaElement-WPF.aspx"/><issued>2008-01-23T12:49:59+01:00</issued><modified>2008-01-23T12:49:59+01:00</modified><slash:comments>1</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2210/Sorgenti-Custom-MediaElement-WPF.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2210.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2210</trackback:ping></entry><entry><title>Anonymous type di C# 3.0</title><id>http://blogs.aspitalia.com/ricciolo/post2197/Anonymous-Type-CSharp-3.0.aspx</id><created>2008-01-04T14:21:18+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2197' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Giocando con &lt;strong&gt;LINQ&lt;/strong&gt; avrete senz'altro usato gli anonymous type: quei tipi creati al volo per contenere varie informazioni. Poniamo questo semplice esempio:&lt;/p&gt; &lt;p class=&quot;colorato&quot;&gt;&lt;code&gt;var v = new {Language = &amp;quot;IT&amp;quot;, Age=30};&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Prima di tutto, v &amp;#232; visibile solo all'interno dello stack in cui l'abbiamo dichiarato. Quindi all'interno di una funzione o metodo, ma mai a livello di classe. Possiamo anche ritornarlo come valore da una funzione, ma potremmo limitarci a ritornare un tipo object generico e non potremmo fare riferimento al nome del tipo, facendo cast o quant'altro (se non via reflection, bleah bleah). Quindi ques'ultima opzione &amp;#232; fortemente sconsigliata.&lt;/p&gt; &lt;p&gt;Quando compiliamo, viene automaticamente generata una classe internal sealed dal nome f__AnonymousType[numero] sul namespace root. La classe eredita da Object definisce n propriet&amp;#224; e n campi per memorizzare i valori e dispone di un costruttore che accetta come parametri i valori da impostare sulle propriet&amp;#224;. Non c'&amp;#232; modo di cambiarne visibilit&amp;#224; ai tipi o ai membri, ne di rendere in sola lettura le propriet&amp;#224;. Questa classe ha la particolarit&amp;#224; di essere generica, nel senso che i tipi string e int delle propriet&amp;#224; Language e Age del nostro esempio, sono generici. Questo per evitare di creare copie della medesima classe. Quindi se utiliziamo nel medesimo assembly un anonymous type simile:&lt;/p&gt; &lt;p class=&quot;colorato&quot;&gt;&lt;code&gt;var v = new {Language = 1, Age=3d};&lt;/code&gt;&lt;/p&gt; &lt;p&gt;verr&amp;#224; utilizzata la medesima classe autogenerata, ma con generics argument diversi: int e double.&lt;/p&gt; &lt;p&gt;Tale classe inoltre sovrascrive ToString per mostrare facilmente il contenuto, Equals e GetHashCode cos&amp;#236; da rendere comparabile il tipo quando viene utilizzato, per esempio da LINQ To Objects:&lt;/p&gt; &lt;p class=&quot;colorato&quot;&gt;&lt;code&gt;[DebuggerHidden] &lt;br /&gt;public override string ToString() &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; StringBuilder builder = new StringBuilder(); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; builder.Append(&amp;quot;{ Language = &amp;quot;); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; builder.Append(this.&amp;lt;Language&amp;gt;i__Field); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; builder.Append(&amp;quot;, Age = &amp;quot;); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; builder.Append(this.&amp;lt;Age&amp;gt;i__Field); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; builder.Append(&amp;quot; }&amp;quot;); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return builder.ToString(); &lt;br /&gt;} &lt;br /&gt; &lt;br /&gt;[DebuggerHidden] &lt;br /&gt;public override int GetHashCode() &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; int num = 0x5b485bf4; // Numero casuale &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; num = (-1521134295 * num) + EqualityComparer&amp;lt;&amp;lt;Language&amp;gt;j__TPar&amp;gt;.Default.GetHashCode(this.&amp;lt;Language&amp;gt;i__Field); &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return ((-1521134295 * num) + EqualityComparer&amp;lt;&amp;lt;Age&amp;gt;j__TPar&amp;gt;.Default.GetHashCode(this.&amp;lt;Age&amp;gt;i__Field)); &lt;br /&gt;} &lt;br /&gt; &lt;br /&gt;[DebuggerHidden] &lt;br /&gt;public override bool Equals(object value) &lt;br /&gt;{ &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var type = value as &amp;lt;&amp;gt;f__AnonymousType0&amp;lt;&amp;lt;Language&amp;gt;j__TPar, &amp;lt;Age&amp;gt;j__TPar&amp;gt;; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return (((type != null) &amp;amp;&amp;amp; EqualityComparer&amp;lt;&amp;lt;Language&amp;gt;j__TPar&amp;gt;.Default.Equals(this.&amp;lt;Language&amp;gt;i__Field, type.&amp;lt;Language&amp;gt;i__Field)) &amp;amp;&amp;amp; EqualityComparer&amp;lt;&amp;lt;Age&amp;gt;j__TPar&amp;gt;.Default.Equals(this.&amp;lt;Age&amp;gt;i__Field, type.&amp;lt;Age&amp;gt;i__Field)); &lt;br /&gt;}&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Sono interessanti l'uso di &lt;strong&gt;DebuggerHidden&lt;/strong&gt; per evitare di far vedere dal debugger tali metodi e l'uso di &lt;strong&gt;EqualityComparer.Default&lt;/strong&gt; per ottenere l'hashcode o comparare i tipi primitivi utilizzati. EqualityComparer.Default restituisce un &lt;strong&gt;IEqualityComparer&amp;lt;T&amp;gt;&lt;/strong&gt; (fondamentale in LINQ) a seconda che il tipo implementi IEquatable&amp;lt;T&amp;gt;, sia nullabile o come ultima spiaggia, sovrascriva Equals e GetHashCode. Per comparare le stringhe (utile sempre in LINQ) abbiamo a disposizione la classe &lt;strong&gt;StringComparer&lt;/strong&gt; che permette diversi modi di comparazione delle stringhe: CurrentCulture, CurrentCultureIgnoreCase, InvariantCulture, InvariantCultureIgnoreCase, Ordinal, OrdinalIgnoreCase.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework/&quot; rel=&quot;tag&quot;&gt;.NET Framework&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/.NET_Framework_3.5/&quot; rel=&quot;tag&quot;&gt;.NET Framework 3.5&lt;/a&gt;, &lt;a href=&quot;http://tags.aspitalia.com/LINQ/&quot; rel=&quot;tag&quot;&gt;LINQ&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2197/Anonymous-Type-CSharp-3.0.aspx"/><issued>2008-01-04T14:21:18+01:00</issued><modified>2008-01-04T14:21:18+01:00</modified><slash:comments>0</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2197/Anonymous-Type-CSharp-3.0.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2197.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2197</trackback:ping></entry><entry><title>Habemus CardSpace!</title><id>http://blogs.aspitalia.com/ricciolo/post2198/Habemus-CardSpace.aspx</id><created>2008-01-03T14:51:00+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2198' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;E' un po' che io e &lt;a onclick=&quot;function anonymous()
{
function anonymous()
{
blankUrl(this.href); return false;
}
}&quot; href=&quot;http://blogs.aspitalia.com/daniele&quot;&gt;Daniele&lt;/a&gt; ci stiamo lavorando (circa due mesi), ma finalmente abbiamo implementato &lt;strong&gt;CardSpace&lt;/strong&gt; nella nostra community. Questo significa che da ora in poi potete fare login utilizzando le card self-issued. Una guida su come funziona l'ambaradam la trovate &lt;a onclick=&quot;function anonymous()
{
function anonymous()
{
blankUrl(this.href); return false;
}
}&quot; href=&quot;https://secure.aspitalia.com/profile/infocard.aspx&quot;&gt;qua&lt;/a&gt; e se avete gi&#224; a disposizione una card e non siente registratati, allora create un profilo &lt;a onclick=&quot;function anonymous()
{
function anonymous()
{
blankUrl(this.href); return false;
}
}&quot; href=&quot;https://secure.aspitalia.com/profile/policy.aspx&quot;&gt;qua&lt;/a&gt;, oppure associate la card ad un account pre esiste, dopo aver fatto il login, andando &lt;a onclick=&quot;function anonymous()
{
function anonymous()
{
blankUrl(this.href); return false;
}
}&quot; href=&quot;https://secure.aspitalia.com/profile/setcard.aspx&quot;&gt;qua&lt;/a&gt;. In generale la vostra card personale &#232; utilizzabile in tutti i portali dove compare questo logo standard:&lt;/p&gt;&lt;p&gt;&lt;img alt=&quot; &quot; hspace=&quot;0&quot; src=&quot;http://blogs.aspitalia.com/img/Ricciolo/CardSpace.png&quot; border=&quot;0&quot; /&gt; &lt;/p&gt;&lt;p&gt;Ovviamente la domanda &#232;: perch&#233; supportare l'identity metasystem?&lt;/p&gt;&lt;p&gt;Risposta:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;perch&#233; adeguarsi ad un sistema standard ed interoperabile ci permette di accogliere nuovi utenti molto pi&#249; facilmente. Basta selezionare la card utilizzata gi&#224; su altri portali e le informazioni sono gi&#224; disponibili; &lt;/li&gt;&lt;li&gt;perch&#233; non serve pi&#249; ricordarsi di password, utenti ed email; &lt;/li&gt;&lt;li&gt;perch&#233; un'unica interfaccia di selezione basata su comunicazioni sicure, &#232; sicuramente meglio dei mille sistemi inventati da ogni programmatore del mondo, abbattendo inoltre cos&#236;, fenomeni come phishing; &lt;/li&gt;&lt;li&gt;perch&#233; questo sistema di autenticazione &#232; utilizzabile anche al di fuori dal web: applicazioni windows, webservice ecc. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Non temete, implementare identity metasystem nei vostri portali &#232; facile e fattibile. L'unica difficolt&#224; &#232; il certificato per il canale SSL, ma dal .NET Framework 3.5 non &#232; pi&#249; obbligatorio se il nostro sito non &#232; una banca :-) La difficolt&#224; che abbiamo incontrato &#232; stata nel cercare di implementare un &lt;strong&gt;STS&lt;/strong&gt; (Security Token Server) per rilasciare delle nostre card marcate ASPItalia.com/WinFXItalia.com, da utilizzare nelle nostre community. Beh dunque, fare un STS non &#232; affatto semplice e il materiale a disposizione non &#232; completo. Parlando comunque con &lt;a onclick=&quot;function anonymous()
{
function anonymous()
{
blankUrl(this.href); return false;
}
}&quot; href=&quot;http://blogs.msdn.com/vbertocci/&quot;&gt;Vittorio Bertocci&lt;/a&gt;, che lavora in Microsoft e si sta dando parecchio da fare per diffondere l'adozione dell'identity metasystem, abbiamo maturato l'idea che fare da STS &#232; troppo per noi. STS che rilascia managed card deve essere un ente, una banca, uno stato. Per la nostra community bastano le semplici self-issued card. Maggiori dettagli tecnici sull'argomento li trovate &lt;a onclick=&quot;function anonymous()
{
function anonymous()
{
blankUrl(this.href); return false;
}
}&quot; href=&quot;http://www.winfxitalia.com/articoli/winfx/gestione-identita-digitali-windows-cardspace.aspx&quot;&gt;qua&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href=&quot;http://tags.aspitalia.com/ASPItalia.com/&quot; rel=&quot;tag&quot;&gt;ASPItalia.com&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2198/Habemus-CardSpace.aspx"/><issued>2008-01-03T14:51:00+01:00</issued><modified>2008-01-03T14:51:00+01:00</modified><slash:comments>4</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2198/Habemus-CardSpace.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2198.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2198</trackback:ping></entry><entry><title>WPF: attenzione ai template predefiniti</title><id>http://blogs.aspitalia.com/ricciolo/post2196/WPF-Attenzione-Template-Predefiniti.aspx</id><created>2008-01-02T13:48:16+01:00</created><content type="text/html" mode="escaped">&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2196' border=&quot;0&quot; style=&quot;width:1px; height:1px;&quot; /&gt;&lt;p&gt;Certo, si pu&amp;#242; dormire lo stesso anche non sapendolo, ma sul nostro &lt;a href=&quot;http://forum.aspitalia.com/forum/29/.net-framework-3.0.aspx&quot; onclick=&quot;blankUrl(this.href); return false;&quot;&gt;forum&lt;/a&gt; &amp;#232; stata posta un'interessante domanda relativa ai Content di &lt;strong&gt;WPF&lt;/strong&gt;. Purtroppo la comodit&amp;#224; di certi elementi presenti ci fa ignorare il dietro le quinte e a volte ci porta a risultati inaspettati. E' il caso delle classi &lt;strong&gt;ContentControl&lt;/strong&gt; e &lt;strong&gt;HeaderedContentControl&lt;/strong&gt; che dispongono delle propriet&amp;#224; &lt;strong&gt;Header&lt;/strong&gt; e &lt;strong&gt;Content&lt;/strong&gt; di tipo Object e ci consentono di fare questo:&lt;/p&gt; &lt;p class=&quot;colorato&quot;&gt;&lt;code&gt;&amp;lt;Button&amp;gt;Ciao!&amp;lt;/Button&amp;gt;&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Innanzitutto tramite l'interfaccia IAddChild la stringa &amp;quot;Ciao!&amp;quot; viene impostata sulla propriet&amp;#224; Content ed equivale quindi a scrivere:&lt;/p&gt; &lt;p class=&quot;colorato&quot;&gt;&lt;code&gt;&amp;lt;Button&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Button.Content&amp;gt;Ciao!&amp;lt;/Button.Content&amp;gt; &lt;br /&gt;&amp;lt;/Button&amp;gt;&lt;/code&gt;&lt;/p&gt; &lt;p&gt;I vari skin applicati a Button o controlli simili, utilizzano l'oggetto &lt;strong&gt;ContentPresenter&lt;/strong&gt; per includere il contenuto nel layout. Quest'oggetto applica dei template predefiniti a seconda del tipo presente in Content:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Se &amp;#232; una stringa e &lt;strong&gt;RecognizesAccessKey&lt;/strong&gt; &amp;#232; a true, utilizza un template che crea un &lt;strong&gt;AccessText&lt;/strong&gt; e con Text valorizzato con il Content stesso; altrimenti utilizza un normale TextBlock con Text valorizzato con il Content stesso;&lt;/li&gt; &lt;li&gt;Se &amp;#232; un &lt;strong&gt;UIElement&lt;/strong&gt;, inserisce l'elemento stesso direttamente come figlio;&lt;/li&gt; &lt;li&gt;Se &amp;#232; un &lt;strong&gt;XmlNode&lt;/strong&gt;, utilizza un TextBlock con Binding XPath = &amp;quot;.&amp;quot;&lt;/li&gt; &lt;li&gt;Per gli altri restanti tipi, utilizza un TextBlock cercando di convertire prima con un &lt;strong&gt;TypeConverter&lt;/strong&gt; e poi con un ToString il tipo impostato come Content.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Detto questo, quali possono essere i risultati inattesi? Prendiamo questo esempio:&lt;/p&gt; &lt;p class=&quot;colorato&quot;&gt;&lt;code&gt;&amp;lt;Menu&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;MenuItem Header=&amp;quot;_One&amp;quot; /&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;MenuItem Header=&amp;quot;_Two&amp;quot; /&amp;gt; &lt;br /&gt;&amp;lt;/MenuItem&amp;gt;&lt;/code&gt;&lt;/p&gt; &lt;p&gt;L'uso degli underscore &amp;#232; riconosciuto da AccessText (il ContentPresenter del MenuItem ha RecognizesAccessKey a true) e permette l'utilizzo dello shorcut effettuando la sottolineatura della lettera che lo segue. Se usiamo per&amp;#242; il Binding XML, per esempio, gli underscore non vengono pi&amp;#249; rinosciuti:&lt;/p&gt; &lt;p class=&quot;colorato&quot;&gt;&lt;code&gt;&amp;lt;MenuItem Header=&amp;quot;{Binding XPath=/item/@text}&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Questo perch&amp;#233; non viene pi&amp;#249; usato il template predefinito riservato alle stringhe. Per ovviare a questo problema, occorre creare in modo esplicito l'oggetto AccessText:&lt;/p&gt; &lt;p class=&quot;colorato&quot;&gt;&lt;code&gt;&amp;lt;MenuItem&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;MenuItem.Header&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;AccessText Text=&amp;quot;{Binding XPath=/item/@text}&amp;quot; /&amp;gt; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/MenuItem.Header&amp;gt; &lt;br /&gt;&amp;lt;/MenuItem&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href=&quot;http://www.aspitalia.com/&quot;&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://blogs.aspitalia.com/ricciolo/post2196/WPF-Attenzione-Template-Predefiniti.aspx"/><issued>2008-01-02T13:48:16+01:00</issued><modified>2008-01-02T13:48:16+01:00</modified><slash:comments>0</slash:comments><wfw:comments>http://blogs.aspitalia.com/ricciolo/post2196/WPF-Attenzione-Template-Predefiniti.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/ricciolo/CommentRSS2196.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2196</trackback:ping></entry></feed>