Wednesday 8 April 2009

Intercettare/Ereditare il DataType per un DataTemplate in xaml

Da qualche mese lavoro ad un progetto dove usiamo WPF integrato con un IOC container (Castle Windsor, tramite l'estensione fornita dal progetto Composite WPF Contrib).

Abbiamo un file xaml simile a questo pseudo-codice:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/
xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Presentation="clr-namespace:XXX.Modules.MyForm.Presentation"
xmlns:WinForms="clr-namespace:XXX.Modules.Common.WinForms"
xmlns:Converters="clr-namespace:XXX.Modules.Common.Converters"

<converters:booleanenumconverter key="YYYConverter">
[snipped other converters]
<DataTemplate DataType="{x:Type
Presentation:MyFormPresentationModel}">
[snipped template xaml]
</datatemplate>
</resourcedictionary>
Ho scritto un paio di intercettori (in pratica usando un componente chiamato Castle Dynamic Proxy, questi generano delle classi che ereditano i componenti registrati con Windsor e che poi si possono usare per intercettare i metodi prima e dopo la loro esecuzione, ad esempio per scrivere dei log o per fare altre cose), ma quando tento di usarli risolvendo i vari componenti intercettati, i DataTemplate definiti nei file xaml dei componenti non risolvono l'oggetto generato (che e' stato istanziato correttamente da Windsor, come posso ad esempio vedere mentre sono in debug), ma ritornano una stringa, che poi altro non e' che il nome del proxy generato (una cosa tipo IMyFormPresentationModelProxy1de831fc74a341249b67...).

Questo e' un comportamento molto simile a quello che incontro quando tento di usare un'interfaccia come DataType del DataTemplate (ad esempio impostando il DataType ad una cosa come "{x:Type Presentation:IMyFormPresentationModel}"), per cui immagino che il DataType non supporti molto bene l'ereditarieta' (o comunque sia piuttosto conservativo nella risoluzione dei tipi).

Dato che non penso che il problema sia nell'IOC o nell'estensione tramite la quale lo integriamo con WPF, immagino che il problema sia quindi che lo "xaml engine" non sia capace di far corrispondere il tipo descritto nel file xaml con quello generato dall'intercettore.

Ho fatto un po di ricerche, ed ho trovato che c'e' gente che per fare cose probabilmente simili (perlopiu' collegate al fatto che il DataType non supporta pienamente i tipi generici, vedi ad esempio "How To Get ParserContext" oppure "Limited generics support in Xaml") usa classi come TypeExtension o MarkupExtension e possibilmente qualche implementazione dell'interfaccia IXamlTypeResolver. Ho anche trovato qualche accenno al possibile uso di un DataTemplateSelector.

Da un punto di vista puramente teorico, l'idea di dover modificare i file xaml per poter intercettare i DataTemplate non mi attrae particolarmente, quindi mi sto chiedendo se per caso non mi sono perso qualcosa.

Prima di investire altro tempo per risolvere il problema (ad esempio scrivendo una mia TypeExtension), sto cercando di chiedere in vari gruppi o mailing list se c'e' qualcuno che abbia esperienza di questo tipo scenario (o qualcuno simile, magari qualcosa che abbia a che fare con l'ereditarieta' ed i tipi definiti in DataType per DataTemplate).

Anche soltanto qualche suggerimento o qualche referenza sarebbe molto gradita :)

Ho gia' scritto un messaggio molto simile sulla mailing list di Castle, ma immagino che questo non sia un bug di Windsor, ma il risultato di una limitazione (o di una scelta progettuale) del DataType.

No comments: