mercoledì 17 aprile 2013
Ultimamente mi sto dilettando su un progetto che utilizza ASP.NET MVC in accoppiata con KnockoutJs.
Si tratta di un'applicazione Single-Page che, tramite AJAX, va a costruire dinamicamente il ViewModel Knockout e che quindi, a seconda della navigazione compiuta dall'utente tramite richieste multiple e asincrone, può diventare "grande" a piacere e difficilmente debuggabile.
Mi è quindi tornato utile questo snippet, che permette di visualizzare lo stato attuale del ViewModel, mostrando tutte le proprietà presenti e i relativi valori, in formato json:
<div style="border: 2px dashed red">
<h1>KnockoutJS ViewModel Viewer:</h1>
<div data-bind="text: ko.toJSON($root)"></div>
</div>
Questo un esempio di quanto verrà stampato a video:

martedì 6 novembre 2012
Il code coverage è un'indice importante per avere un'idea della percentuale di codice coperto da unit-test.
Se utilizzate il framework di unit-test Microsoft (MSTest), Visual Studio è in grado di calcolare tale indice automaticamente (maggiori dettagli qui).
Tempo fa avevo instrumentato questo tool su un mio progetto ed oggi, dopo aver fatto refactoring ed aggiunto alcune funzionalità, volevo visualizzare i dati di code coverage.
Lanciando il tool, ottenevo tuttavia questo messaggio:
"Cannot find any coverage data (.coverage or .coveragexml) files. Check test run details for possible errors."
Dopo un pò di verifiche ho scoperto l'inghippo: per qualche motivo il file di impostazioni dei test corrente era "Trace and Test Impact" e non "Local".

giovedì 23 agosto 2012
Dalla versione 4.5 del .NET framework è finalmente supportata out-of-the-box la manipolazione di file zip senza l'utilizzo di librerie di terze parti.
Sono ora disponibili infatti 2 assembly System.IO.Compression e System.IO.Compression.FileSystem che permettono, ad esempio, di enumerare i file presenti in uno zip, estrarli, creare nuovi file zip, etc.
Ad esempio, ecco come si ottiene l'elenco dei file contenuti in uno zip:
const string zipFilePath = @"C:\temp\files.zip";
using (FileStream zipFileToOpen = new FileStream(zipFilePath, FileMode.Open)){
using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Read)) {
foreach (var zipArchiveEntry in archive.Entries) {
Console.WriteLine("File name: {0}", zipArchiveEntry.FullName);}
}}
E come si estraggono in una directory:
const string zipFilePath = @"C:\temp\files.zip";
const string dirToExtract = @"C:\temp\";
using (FileStream zipFileToOpen = new FileStream(zipFilePath, FileMode.Open)) {
using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Update))
archive.ExtractToDirectory(dirToExtract);}}
Vi lascio quindi i riferimenti di MSDN:
ZipArchive Class
System.IO.Compression
mercoledì 22 agosto 2012
Una delle cose che più mi piacciono di JQuery è la facilità con la quale è possibile estendere le sue funzionalità.
Ecco infatti come è possibile implementare le funzioni per attivare e disattivare gli elementi del DOM:
// Set an element as enabled, if supported
$.fn.enable= function () {
return this.each(function () {
if (typeof this.disabled != "undefined") {
this.disabled = false;
}
});
};
// Set an element as disabled, if supported
$.fn.disable = function () {
return this.each(function () {
if (typeof this.disabled != "undefined") {
this.disabled = true;
}
});
};
In questo modo è possibile (dis)abilitare qualsiasi elemento con i soliti selettori JQuery:
$("*").enable();
$(".editor").disable();
lunedì 11 giugno 2012
Se negli ultimi anni non avete vissuto su Marte, avrete sicuramente sentito parlare dell’interfaccia Metro (per i marziani, ecco un link che vi spiega velocemente cos’è
).
Nel caso stiate sviluppando applicazioni per Windows Phone o Windows 8 (le famose Metro App), avrete già tutti i controlli disponibili che seguono questo stile, senza dover adottare alcun accorgimento particolare..
E nel caso di applicazioni WPF?
Bhè, esiste il toolkit di Mahapps, che ci omaggia di una serie di controlli, stili, behaviors e attached properties che fanno proprio al caso nostro!
Come potete vedere il risultato è notevole, e senza particolari stravolgimenti del nostro Xaml:

Metro is everywhere! 
P.S: Anche per il web sono disponibile progetti interessanti (es link1 , link2)
giovedì 5 aprile 2012
Recentemente ho dovuto creare un’applicazione WPF che fosse facilmente distribuibile (leggi: distribuire solo l’exe).
Purtroppo il tool ILMerge non funziona per applicazioni WPF, a causa di problemi con le risorse contenute in esse (esistono comunque tool funzionanti di terze parti, a pagamento).
Seguendo questo post, ho creato un esempio che qui illustro e che potete scaricare qui.
L’applicazione visualizza semplicemente il fullname di due classi presenti in 2 assembly referenziati:

Per prima cosa è necessario modificare il file di progetto dell’applicazione WPF aggiungendo, dopo “Microsoft.CSharp.targets” , il seguente snippet:
- <Target Name="AfterResolveReferences">
- <ItemGroup>
- <EmbeddedResource Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.Extension)' == '.dll'">
- <LogicalName>%(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension)</LogicalName>
- </EmbeddedResource>
- </ItemGroup>
- </Target>
Semplicemente, andiamo ad indicare di inserire tutti i file referenziati con estensione “.dll” come “emdedded resource” nell’exe principale. In questo modo eviteremo di eseguire a mano l’inclusione dell’ultima versione delle librerie compilate.
Nelle proprietà del progetto, impostiamo il seguente comando da eseguire durante la fase di post-build: “del $(TargetDir)*.dll” per cancellare tutte le librerie presenti nella “bin”, che non ci serviranno più...

Impostiamo quindi come oggetto di avvio la classe Bootstrapper (potete ovviamente cambiare il nome):

Questa, infine, è come definita la classe BootStrapper:
- public class BootStrapper
- {
- [STAThread]
- public static void Main(string[] args)
- {
- AppDomain.CurrentDomain.AssemblyResolve += OnResolveAssembly;
- App.Main();
- }
-
- private static Assembly OnResolveAssembly(object sender, ResolveEventArgs args)
- {
- var executingAssembly = Assembly.GetExecutingAssembly();
- var assemblyName = new AssemblyName(args.Name);
-
- string path = string.Format("{0}.dll", assemblyName.Name);
- if (assemblyName.CultureInfo.Equals(CultureInfo.InvariantCulture) == false)
- {
- path = string.Format(@"{0}\\cf4 {1}", assemblyName.CultureInfo, path);
- }
-
- using (var stream = executingAssembly.GetManifestResourceStream(path))
- {
- if (stream == null)
- {
- return null;
- }
-
- var assemblyRawBytes = new byte[stream.Length];
- stream.Read(assemblyRawBytes, 0, assemblyRawBytes.Length);
- return Assembly.Load(assemblyRawBytes);
- }
- }
- }
Sostanzialmente ci agganciamo all’evento AssemblyResolve dell’AppDomain corrente, che viene sollevato ogni volta che la risoluzione di un’assembly fallisce, e ritorniamo l’assembly che abbia in canna nelle embedded resources.
Ecco infatti come si presenta il nostro exe “aprendolo” con ILSpy:

E’ anche più semplice di usare la riga di comando di ILMerge ! 
martedì 3 aprile 2012
Recentemente ho dovuto realizzare una sorta di wizard in WPF, ovvero una classica window con un’intestazione, una listbox a sinistra che visualizza gli step (evidenziando lo step corrente) e un contentpresenter in cui verrà caricato il contenuto dinamicamente. Niente di complicato.
La cosa “particolare” è il fatto che la listbox con l’elenco degli step è read-only, ovvero deve solo presentare i dati e l’utente non deve poter selezionare qual’è lo step corrente..altrimenti che procedura guidata è?
.
Ovviamente è possibile disabilitare la listbox , ma in questo modo lo stile applicato rende il tutto poco usabile e gradevole (un grigio che mina la leggibilità del controllo )..e di certo non mi andava di rifare il template del controllo per questa sciocchezza.
Ho risolto semplicemente creando uno style per l’ItemContainer e impostando a false la proprietà Focusable:
- <ListBox.ItemContainerStyle>
- <Style TargetType="{x:Type ListBoxItem}">
- <Setter Property="Focusable" Value="False"/>
- <Style.Triggers>
- <Trigger Property="IsSelected" Value="True">
- <Setter Property="FontWeight" Value="Bold" />
- </Trigger>
- </Style.Triggers>
- </Style>
- </ListBox.ItemContainerStyle>
Thanks WPF!
martedì 10 gennaio 2012
Se utilizzate AutoMapper per creare Dto da oggetti letti con Nhibernate e lazy-loading attivo, è possibile che otteniate un’eccezione di tipo ObjectDisposedException, in quanto Automapper accede a proprietà “Lazy”, ma la sessione è già stata chiusa e distrutta.
Per risolverlo, basta implementare un Custom Resolver, che tornerà null qualora il tipo della proprietà che sto provando a mappare sia un proxy non inizializzato.
Ecco quindi il codice:
- public class NhProxyResolver : ValueResolver<object, object>
- {
- protected override object ResolveCore(object source)
- {
- return NHibernateUtil.IsInitialized(source) ? source : null;
- }
- }
ed un esempio della configurazione di AutoMapper:
- Mapper.CreateMap<User, UserDto>()
- .ForMember(x => x.Orders, opt => opt.ResolveUsing<NhProxyResolver>().FromMember(z => z.Orders));
martedì 28 febbraio 2012
Recentemente mi è tornato utile avere l’elenco delle transazioni attive con il relativo statemente T-SQL.
Ecco la query che ho utilizzato:
SELECT s_tst.[session_id],
s_es.[login_name] AS [Login Name],
DB_NAME (s_tdt.database_id) AS [Database],
s_tdt.[database_transaction_begin_time] AS [Begin Time],
s_tdt.[database_transaction_log_record_count] AS [Log Records],
s_tdt.[database_transaction_log_bytes_used] AS [Log Bytes],
s_tdt.[database_transaction_log_bytes_reserved] AS [Log Rsvd],
s_est.[text] AS [Last T-SQL Text],
s_eqp.[query_plan] AS [Last Plan]
FROM sys.dm_tran_database_transactions s_tdt
JOIN sys.dm_tran_session_transactions s_tst
ON s_tst.[transaction_id] = s_tdt.[transaction_id]
JOIN sys.[dm_exec_sessions] s_es
ON s_es.[session_id] = s_tst.[session_id]
JOIN sys.dm_exec_connections s_ec
ON s_ec.[session_id] = s_tst.[session_id]
LEFT OUTER JOIN sys.dm_exec_requests s_er
ON s_er.[session_id] = s_tst.[session_id]
CROSS APPLY sys.dm_exec_sql_text (s_ec.[most_recent_sql_handle]) AS s_est
OUTER APPLY sys.dm_exec_query_plan (s_er.[plan_handle]) AS s_eqp
ORDER BY [Begin Time] ASC;
Utile nel caso di transazioni bloccate\bloccanti!
martedì 20 dicembre 2011
Come tutti sapete all’interno di Visual Studio (pannello “Solution Explorer”) è possibile creare cartelle in cui andremo inserire le nostre classi.
Per impostazione predefinita, la struttura di queste cartelle andrà a definire quello che viene chiamato Fully qualified name (FQN), ovvero il nome che identifica in modo univoco la nostra classe: Namespace.NomeClasse.
Pertanto, se la nostra solution è organizzata in questo modo

il FQN di customer sarà Sample.Domain.Customer.
Mano a mano che il progetto cresce potremmo trovarci in situazioni in cui la cartelle contengono raggruppamenti logici di file che tuttavia non vogliamo entrino in gioco nella costruzione del FQN.
Per esempio, se nella cartella Domain creiamo una sottocartella Customer

Resharper ci segnala che il namespace della classe non è coerente con la posizione del file:

Per risolvere il “problema” (ovviamente il progetto compila lo stesso, ma è una segnalazione utile per mantenere lo standard qualitativo del codice) basta impostare a False la voce “Namespace Provider” tra le proprietà della cartella.
