Posts
46
Comments
81
Trackbacks
12
martedì 25 novembre 2008
Reflection: estrarre l’unico tipo di un assembly che implementa un’interfaccia


Oggi mi si è presentata la necessità di dover estrarre da un assembly, di cui conoscevo solo il nome (AssemblyName.dll), l’unico tipo che implementasse una determinata interfaccia (IFoo).

Bene…non essendo un grande esperto di Reflection e di tutto quanto le gravita attorno, non ho avuto scelta: partire dai test!!!
NOTA: avrei fatto lo stesso anche se sapevo dove andare a parare ;-)

Step01

L’assembly “AssemblyWithOneContainer” è un assembly che, come dice il nome stesso, contiene un solo oggetto che implementa l’interfaccia richiesta.
Ok, ora che la strada è tracciata posso provare ad implementare la funzionalità…reflection & LINQ si sono rivelati un’ottima accoppiata per risolvere la situazione in modo “brillante”. Ecco la soluzione:

Step02

o in modo ancora più compatto:

Step03 

- melkio -

posted @ martedì 25 novembre 2008 16.34 | Feedback (0)
lunedì 17 novembre 2008
TechEd 2008 – Riassumendo…

Dopo una settimana in quel di Barcellona, ed un week-end di “stacco” per elaborare il tutto, ecco il mio riassunto di questa fantastica esperienza.

Sotto il punto di vista tecnico mi posso ritenere del tutto soddisfatto. Ovviamente, come altri hanno già riportato, alcune sessioni erano ottime, mentre altre, anche di livello 300, lasciavano alquanto a desiderare. Diciamo che sono stato abbastanza bravo e fortunato a trovare sessioni appropriate ;-)
Per quanto riguarda l’organizzazione io non posso fare paragoni con esperienze precedenti, e quindi mi limito a “giudicare” solo il discorso alimentare: assolutamente insufficiente. Quattro giorni su cinque ho preferito saltare il pranzo piuttosto che “rovinarmi il fegato” con i panini insacchettati…recuperavo la sera ;-)

SyncFramework
Ottimo!!! L’avevo utilizzato nella sua versione “primordiale” per allineare semplicemente due basi dati. Nulla di particolarmente complesso, ma la customizzazione/creazione di nuovi provider, mi aveva spaventato non poco, procurandomi più di un grattacapo.
Con la nuova versione, le cose dovrebbero essersi notevolmente semplificate…ci devo studiare ancora un po’, spero a breve di potervi ragguagliare con delle news più approfondite

WPF
L’avevo intuito (eufemismo, ovviamente), ma questo TechEd, l’ha confermato: WPF è il futuro!!! Grande attenzione alle performance, grande attenzione al “non esagerare”, ma enormi (infinite?) possibilità. WPF, ancora più che WinForm, introduce un livello di complessità non elementare; utilizzarlo significa anche conoscere gli “internals” di questo framework. Basti pensare che in una demo, senza togliere alcun effetto “esoterico”, ma ottimizzando qua e là (non a caso, ovviamente), lo speacker ha mostrato come ottimizzare un’applicazione sviluppata in WPF, passando da 1Gb (e passa) di memoria utilizzata a poche decine di Mega

Windows Azure
Il futuro: idea interessante e innovativa…credo che in Italia (almeno per la situazione che posso vivere tutti i giorni io), dovremo stare con i piedi ben piantati per terra per parecchio tempo ancora, tralasciando voli “on the cloud”.
Faccio fatica a pensare ad un SAP-on-the-cloud o ad un AS400-on-the-cloud…ma solo il tempo potrà darci una risposta!
Per poter sfruttare le potenzialità di questa piattaforma, comunque, dovremo rivedere anche l’architettura delle nostre applicazioni, cosa per nulla semplice quando le applicazioni non sono fatte con “criterio” e soprattutto quando le tecnologie in gioco non sono del tutto “conformi” a questo cambio di direzione

TFS
Un discorso a sè stante lo meritano le due sessioni su TFS che ho seguito. In questo ultimo periodo, più di una volta, ho buttato l’occhio a TFS e l’idea che mi ero fatto era quella di uno strumento indispensabile per la gestione del ciclo di vita del software, soprattutto per quelle realtà medio-grandi che sono strutturalmente ben definite. Per intenderci, ad alcuni miei clienti che fino a ieri utilizzavano uno share di rete per condividere il codice sorgente, ho sempre suggerito, seguendo la politica dei piccoli passi, di installare svn come repository, pensando che TFS fornisse molto, ma molto di più di quello che avrebbe potuto servirgli.
Mi sbagliavo!!!
La possiblità di customizzazione “spinta” di TFS permette di modellare a proprio piacimento le modalità che questo strumento ci mette a disposizione per aiutarci nella gestione del ciclo di vita della nostra soluzione, partendo, magari, da un modello semplicissimo per poterlo ampliare mano a mano che si presentano nuove necessità. Veramente ottimolo strumento (ma già lo sapevo)
Un plauso va anche allo speacker:
Neno Loje…di gran lunga il migliore degli speaker che ho avuto la possibilità di seguire!!!

Ultima nota, ma non per importanza, un ringraziamento sincero a chi ha condiviso con me questa esperienza, rendendo ancora più divertente/gratificante/leggera (e chi più ne ha, più ne metta) la settimana appena trascorsa: auliNino, Corrado, il mio compagno di merende, MauroRaffaele (l’ordine è puramente alfabetico e spero di non aver dimenticato nessuno).

--
melkio

posted @ lunedì 17 novembre 2008 13.36 | Feedback (6)
domenica 5 ottobre 2008
it-TDD

In questi giorni (a dir la verità oramai sono un po’ di settimane…ma il mio tempo di risposta si sta facendo un po’ troppo lungo :-( ), sulla ML di ugialt.net è in corso una discussione sul perchè la pratica del TDD sia poco diffusa nelle aziende italiane e sul perchè sia così difficile farla adottare.

Oltre alle solite motivazioni riconducibili al “qui in Italia siamo sempre N anni indietro”, volevo provare a guardare la situazione da un altro punto di vista, quello delle aziende, portando la mia “esperienza” come consulente in alcune di queste aziende.

Bisogna partire, secondo me, dal concetto che “fare TDD” solo perchè fa figo, senza capirne vantaggi e svantaggi è solo deleterio: ci si trova con tonnellate di codice (test + produzione) da manutenere, il tempo a disposizione si riduce e quindi si accelerano i “battiti” e la prima cosa che si taglia sono i test…ecco avere un progetto testato a metà è peggio che non averlo testato per nulla: si ha una effimera sicurezza dettata dai test parziali che si rivela estremamente controproducente.
Sviluppare applicazioni utilizzando come pratica il “farsi guidare dai test” non è affatto facile, la rampa di apprendimento iniziale è abbastanza ripida e molte aziende identificano in questa iniziali difficoltà il fatto che i tempi di sviluppo si dilatano esponenzialmente. Non è assolutamente facile, soprattutto all’inizio, ma anche dopo parecchia pratica, scrivere test veramente unitari e codice fortemente disaccoppiato per rendere il tutto facilmente testabile.
Ma perchè introdurre tutte queste interfacce, quando con un’unica classe e un paio di metodi riesco ad ottenere lo stesso risultato? Questa è la domanda che sempre più frequentemente mi viene posta e sinceramente, oltre alla mia risposta “puramente teorica” (codice più testabile, fortemente disaccoppiato e quindi riutilizzabile e sostituibile…), quando si tocca il discorso tempistiche di rilascio, faccio fatica a controbattere.

La pratica del TDD è una metodologia di sviluppo software che va appresa con il tempo, con la pratica e sopprattutto con tanti sacrifici…non è assolutamente facile e immediata, ma non per questo alle prime difficoltà si deve abbandonare: i benefici, nel medio/lungo periodo, sono sicuramente superiori ai disagi (e ritardi) iniziali. Nel mondo reale, non sempre (quasi mai?!?!?) le aziende, e quindi i loro team di sviluppo, hanno la possibilità di investire tempo e risorse per poter fronteggiare le difficoltà iniziali…è proprio in questo periodo iniziale che come consulente “praticante” (del TDD) *devo* essere più vicino a questi team per farli sentire più sicuri (in futuro ci penseranno i test), per non farli barcollare alle prime difficoltà e non demordere nel vedere i tempi dilatarsi (entro un limite ragionevole ovviamente) e soprattutto devo essere più chiaro e convincente nello spiegarne i benefici.

Alla prossima
-melkio-


 

posted @ domenica 5 ottobre 2008 0.30 | Feedback (1)
lunedì 15 settembre 2008
WPF & Composite Application Block (CAB)

Visto che sono stato tirato in ballo esprimo la mia opinione sul framework in oggetto (e in generale sulla frameworkite di noi sviluppatori).

Come ha detto Ema, stiamo utilizzando il CAB per WPF in un progetto che stiamo sviluppando insieme e quindi stiamo "sbattendo la testa" sulle problematiche reali dell'utilizzo di questo framework.

In passato avevo utilizzato la SCSF (estensione del CAB per WinForm) per un grosso progetto e l'impressione era stata tutt'altro che positiva: troppo vincolante e troppo articolato. L'utilizzo di questi framework sono, secondo il mio punto di vista, fortemente consigliati in team che hanno bisogno di una certa rigidità, vista nella sua accezione positiva. Ovvero nella standardizzazione "spinta" del codice, in modo che tutti i componenti del team abbiano una linea guida da seguire.
Ma proprio qui sta, secondo me, la chiave di volta: regole troppo rigide e non definite/nate dal team e dalle sue esigenze (in fin dei conti il framework è già fatto) possono portare ad un rigetto. Molte volte, una struttura rigida, impone scelte "discutibili" che portano i programmatori a cercare workaround per accelerare i tempi di sviluppo ottenendo quindi l'effetto contrario: ognuno rispetta le proprie linee guida, e della standardizzazione/uniformità del codice se ne perdono le tracce.

Partendo da questo presupposto, il mio primo impatto con questo framework (CAB per WPF) è partito all'insegna della diffidenza, parzialmente "allentata" con il suo utilizzo: in effetti questo framework nasce sotto una luce diversa. Per prima cosa non necessita più di quel cubo impenetrabile che era l'ObjectBuilder dell'EnterpriseLibrary, ma utilizza un container di IoC (di default Unity) più smart per iniettare le dipendenze e per garantire una testabilità più elevata.

E' secondo me, sicuramente, un passo avati rispetto al CAB per WinForm, ma...come al solito c'è sempre un ma.
Sempre più mi sto rendendo conto della necessità di non reinventare tutte le volte la ruota e in questo certi aiuti sono sicuramente bene accetti: mai e poi mai mi immaginerei ora di mettermi a scrivere un layer di accesso ai dati di sana pianta (a meno di specifiche richieste)...c'è NHibernate che mi da una mano. Idem per iniettare le dipendenze: non faccio più nulla a mano, ma utilizzo Spring. Un grosso aiuto con il minimo sforzo!!!!

Utilizzare questi framework mi impone di sviluppare la mia applicazione seguendo certi vincoli, ma i vantaggi che mi danno sono molto, ma molto, superiori rispetto alle "noie" che *possono* procurarmi.
Ecco, il discorso sta tutto qua: non dico che il CAB non sia un ottimo framework (certo si può sempre far edi meglio, vista la fatica per sostituire Unity con Spring...ma questo è un altro discorso), ma dico solamente che i vantaggi che mi da (gestione delle region e *forse* gestione dei moduli) non sono così "vantaggiosi" rispetto ai vincoli che mi impone e alle rigidità che presenta.

Magari utilizzandolo più assiduamente ed entrando di più nel "cuore pulsante" del CAB ne troverò altri vantaggi e allora...ve li comunicherò e rivedrò la mia posizione, ma per ora dico: "Ema se mi avessi ascoltato..." :-)

melkio

posted @ lunedì 15 settembre 2008 8.04 | Feedback (3)
venerdì 18 aprile 2008
[WPF] starting problems

Per chi ha da sempre programmato utilizzando WindowsForm le novità introdotte con l'avvento di WPF sono veramente tante.

Mi sono accorto però, supportando alcuni team nell'approccio a WPF, che il primo vero scoglio/novità che si incontra "migrando" verso questa nuova tecnologia è la filosofia su cui si basa il sitema di layout.
L'utilizzo (corretto) di WPF "spinge" verso la definizione di un layout fluido, combinando i vari container a disposizione, e non più posizionale. Viene enfatizzato il concetto di creazione di un layout più flessibile che possa adattarsi correttamente al ridimensionamento delle window e al cambiamento dei dati contenuti/presentati.

Non che con WinForm questo non fosse possibile (TableLoyoutPanel e FlowLayoutPanel docet), ma con WPF questo modo di "fare layout" è lo standard de-facto (a meno di particolari esigenze, come per esempio la fase di "drawing").
Non credo di esagerare dicendo che WPF sovverte completamente il modello di layouting del .Net fx 2.0, rendendo il "flow-based" layout lo standard e fornendo un supporto "semplice" per il layout posizionale.

Una volta superato questo primo scoglio...bhe ci sono le DependencyProperty, i RoutedEvent, il DataBinding, gli Stili e chi più ne ha più ne metta ;-)

Che ne pensate?

posted @ venerdì 18 aprile 2008 1.42 | Feedback (4)
mercoledì 27 febbraio 2008
[NH] Delete...something

Con NH è "molto semplice" gestire il life-cycle di un oggetto, ma a volte nasce l'esigenza di poter effettuare operazioni che esulano dalle semplici CRUD sulla singola entità.

Un esempio semplice è quello che mi è capitato oggi: cancellare, a fronte di una certa operazione dell'utente, tutti i record di una tabella che avevano particolari requisiti.
Che fare? Caricare tutte le entità in questione e poi cancellarle una ad una? naaaaaaaaaaaaaaaaahhhhhhhhhhhhhh!!!

La session di NH mette a disposizione il metodo Delete con quattro overload. Il primo, quello di cui sopra, per l'eliminazione del singolo oggetto. Gli altri tre permettono di specificare una query SQL o HQL per definire quali sono gli elementi che devono essere eliminati.

Per fare un semplice esempio, svuotare la tabella degli utenti:

session.Delete("from User");

Facile no?

posted @ mercoledì 27 febbraio 2008 10.47 | Feedback (0)
mercoledì 20 febbraio 2008
[WPF] WPF.Start()

Come per qualunque altra applicazione, anche le applicazioni WPF hanno bisogno di un entry point, ovvero il famoso metodo "Main" decorato con l'attributo [STAThread].

Con WPF abbiamo (almeno) tre modi per poter definire quale deve essere il "punto di ingresso" della nostra applicazione. Tralasciando il tradizionale metodo "lato C#" analiziamo gli altri due modi (molto simili) che XAML ci mette a disposizione:

1. Creo un file EntryPoint.xaml e il relativo EntryPoint.cs e li "lego" tra di loro:

2. Creo un unico file EntryPoint.xaml senza dover necessariamente definire il relativo file EntryPoint.cs

 

NOTA: In entrambi i casi la build action del file xaml deve essere impostata su ApplicationDefinition.

Dando un occhio alla cartella obj del nostro progetto, si nota subito che, in entrambe le soluzioni il compilatore genera un file EntryPoint.g.cs praticamente identico, se non per il fatto che, nel secondo caso, non avendo un corrispondente file C# con un namespace correttamente definito, il compilatore assegna al file creato il namespace XamlGeneratedNamespace.
E' in questo file che viene generato, oltre al metodo InitializeComponent(), il metodo che fungerà da entry point per la nostra applicazione:

Sarà che sono prolisso, sia quando parlo, sia quando scrivo, ma l'idea che il codice deve essere autoesplicativo ha sempre caratterizzato il mio modo di vedere...insomma se devo scegliere, preferisco di gran lunga la prima e più "completa" soluzione.

posted @ mercoledì 20 febbraio 2008 23.06 | Feedback (6)
lunedì 28 gennaio 2008
[LINQ2SQL] Modalità di caricamento

Nell'ottica di sfruttare al meglio le potenzialità di un ORM in genere, e di LINQ2SQL in particolare (anche se a mio modesto parere è un "ibrido") bisogna, come da molte parti è già stato suggerito, "ricordarsi di non dimenticare" che sempre con un database relazionale abbiamo a che fare.
Questo preambolo per dire che il miglior suggerimento che si può dare a chi inizia ad utilizzare Linq2Sql è quello di non dimenticarsi MAI di abbinare l'utilizzo di un profiler per vedere cosa stiamo cercando di far fare al nostro db...

In un semplice esempio (il database di riferimento è il "famoso" AdventureWorks) possiamo notare come l'utilizzo fuori controllo di designer e strumenti RAD possono "deviare" dal corretto/miglior utilizzo delle tecnologie che abbiamo a disposizione:

 

Di default il caricamento definito nel DataContext è un "caricamento tardivo", quindi nell'esempio di codice seguente il caricamento degli indirizzi che soddisfano il criterio impostato viene scatenato nel momento in cui inizia l'iterazione sul risultato, all'interno del ciclo foreach.
La selezione del nome dello stato (o della provincia) associata all'indirizzo corrente scatena, ad ogni ciclo nuovi round-trip sul database, se l'oggetto StateProvince non è ancora stato caricato (non presente nel DataContext).

E il risultato del profiler è impietoso...

Questo semplice caso è lampante e mette in evidenza come, senza conoscere la modalità con cui Linq2Sql "mappa" le nostre query, rischiamo veramente di mettere sotto-stress il database, facendolo lavorare nel modo a lui meno congeniale.

Per un corretto caricamento (in questo caso), bisogna istruire il DataContext affinchè i round-trip sul database siano limitati e quindi le n-select precedenti siano effettivamente un'unica richiesta sulle tabelle degli indirizzi e degli stati legate tramite una join.

Così facendo il risultato la query creata da Linq2Sql, diciamo così, mi piace di più:

exec sp_executesql N'SELECT
[t0].[AddressID],
...
[t1].[StateProvinceID]
...
FROM [Person].[Address] AS [t0] INNER JOIN [Person].[StateProvince] AS [t1] ON [t1].[StateProvinceID] = [t0].[StateProvinceID]
WHERE [t0].[City] LIKE @p0',N'@p0 nvarchar(2)',@p0=N'A%'

posted @ lunedì 28 gennaio 2008 9.34 | Feedback (1)
venerdì 25 gennaio 2008
[WinForm] Rendere trasparente un controllo

Esistono due tipologie di trasparenza per il background di un controllo:

  • Il controllo è reso trasparente per rendere visibile la form sottostante.
    Per ottenere questo risultato basta semplicemente impostare il valore della property BackColor del controllo a Color.Transparent, come nell'esempio seguente:

 

  • Il controllo è reso trasparente in modo da rendere visibile il desktop sottostante.
    Per ottenere questo risultato, bisogna impostare la property TransparencyKey della form che contiene il controllo e la proprietà BackColor del controllo stesso, al medesimo valore, come nell'esempio seguente:

posted @ venerdì 25 gennaio 2008 2.16 | Feedback (0)
lunedì 21 gennaio 2008
[WinForm] RichTextBox & AllowDrop

Questa sera, implementando la funzione di Drag&Drop verso un oggetto di tipo RichTextBox, mi sono accorto di una strana scelta di "design" relativa a questo oggetto.
La proprietà AllowDrop (e così anche gli eventi DragEnter e DragDrop), derivata dalla classe base Control, oltre a essere ridefinita (e fin qui, "poco male") è anche "marchiata" come Browsable = false, rendendola invisibile a design-time nella finestra delle proprietà.

Certo, non è un gran problema...è possibile nel costruttore della Form, piuttosto che nell'evento Load, impostare il tutto molto semplicemente nel modo seguente:

...ma questa proprio non l'ho capita!

Alla prossima
-melkio-

posted @ lunedì 21 gennaio 2008 10.54 | Feedback (0)