Programming Languages Hacks

Importanti regole per linguaggi di programmazione rilevanti come Java, C, C++, C#…

  • Subscribe

  • Lettori

    I miei lettori abituali

  • Twitter

Riuso o Automazione – come ottenere un riuso al 100% personalizzabile

Posted by Ricibald on June 26th, 2013

Riuso con libertà assoluta di customizzazione… Connubio possibile?

Ricordiamo la metafora per i design pattern:

a * b + a * d = a * (b + d)

Significa che l’essenza dei design pattern e della buona programmazione sta nel riuso: più si riesce a centralizzare maggiore è la consistenza e l’efficienza che si ottiene.
L’efficienza è ovvia: centralizzando riusciamo a non riscrivere codice e quindi a ottimizzare il nostro lavoro. Centralizzare significa ottenere consistenza: se check di errori o log esiste nel metodo centralizzato, sarà propagata ovunque tra i chiamanti.

Esistono però ambiti dove il riuso è necessario ma molto arduo a causa delle esigenze specifiche del contesto. Un esempio tipico sono le UI (User Interface).

Immaginiamo un modello complesso da visualizzare, con 100 proprietà di tipi diversi. Nella visualizzazione o edit del modello dobbiamo visualizzare o modificare in modo consistente tutte le proprietà per conferire un look & feel autorevole. D’altra parte la visualizzazione non può nemmeno essere troppo rigida poiché si perderebbe quella flessibilità per visualizzare o modificare in modo speciale particolari proprietà. Il discorso potrebbe non essere limitato alle singole proprietà ma anche al layout stesso: potrebbe richiedere raggruppamenti speciali opzionalmente collassabili, funzionalità di drag & drop, autocompletamento, dialog ajax, popup di conferma, validazione ajax, …

Come ottenere il riuso con la giusta flessibilità?

Ci sono diverse possibilità in questo caso per ottenere il riuso con la flessibilità desiderata:

  • copia e incolla: più che di riuso si parla di “riciclo”. È una soluzione svantaggiosa? Da moltissimi punti di vista sì, ma la replicazione del codice ha anche vantaggi come la diminuzione del rischio globale (se fallisce una libreria base non fallisce tutto) e libertà assoluta di customizzazione. Ovviamente avremo bassissima consistenza ed efficienza
  • micro funzionalità fornite tramite helper: che siano classi di check, design pattern complessi, risorse (css/js), user control, html helper, aspetti, interceptor o extension method tali componenti di appoggio consentono di scrivere codice di più alto livello disinteressandoci di dettagli tecnici come log, caching, verifica errori, generazione html, transazionalità, undo metodi, … Passando opportuni parametri o implementazioni specifiche (Pattern Strategy) possiamo personalizzarne il comportamento (es. se loggare o meno) rendendole scelte comunque flessibili. Normalmente agiscono però a un basso livello: l’orchestrazione dobbiamo sempre implementarla
  • intera funzionalità autogenerata: ci troviamo nel caso più estremo, rendendo il tutto molto più consistente ma anche molto più rigido. Utilizzando metadati (da file, attributi, reflection, convenzioni, codice tramite model specializzati…) o generando codice che abilita il pattern Template Method (es. partial method) possiamo avere dei gradi di customizzazione sulle singole micro funzionalità e sull’orchestrazione stessa. Questa tecnica funziona bene e ha differenti gradi di libertà ma richiede lo sforzo di costruire un framework la cui definizione di metadati potrebbe essere non banale per ottenere il comportamento “ipotizzato” (il risultato finale potrebbe essere difficile da prevedere e non immediato). Infine, la generazione ha comunque un costo computazionale a ogni pagina generata da valutare.
  • intera funzionalità pregenerata: sembra lo stesso caso precedente, in realtà è una generazione su file che sfrutta internamente gli helper. È come se avessimo scritto noi il codice “a mano” ma in realtà è stato generato su file basandosi su metadati. Lo scopo è quello di ricondursi al secondo caso nella lista, in cui costruiamo ogni micro funzionalità tramite helper, ma risparmiando l’onere di riscrivere l’intera orchestrazione. Questo consente che l’orchestrazione sia liberamente editabile: non si otterrà la consistenza nell’orchestrazione (le modifiche in un flusso condiviso devono essere propagate a mano) ma si guadagna in efficienza. Inoltre non inficia in tempi di calcolo. Le tecniche possono essere applicazioni standalone o integrate nell’IDE come i Text Template (T4) che consentono di definire MVC Template.
  • intera funzionalità pregenerata solo su richiesta, altrimenti autogenerata: è un ibrido tra le due. Di base viene autogenerata la funzionalità magari ottimizzandone i tempi tramite un precaching e solo in caso di esigenze particolari di customizzazione si richiede esplicitamente di creare la funzionalità pregenerata su file su cui si avrà completa libertà di azione, ma partendo da uno scheletro già completamente funzionante. Un ottimo esempio in questo senso è ASP.NET Dynamic Data

Il concetto in questo post è stato generalizzato (guarda caso…) ma si può leggere “funzionalità” come “proprietà da visualizzare in input (html)” e “orchestrazione” come “layout della pagina web”: i principi si applicano quindi tranquillamente anche in un contesto web.

Non esiste solo il riuso classico…

Questo post voleva evidenziare i diversi livelli per generalizzare e abilitare il riuso: spesso ci si basa solo sulla seconda soluzione vedendo il riuso solo come la costruzione di componenti e l’utilizzo sapiente di design pattern. In realtà esiste un livello spesso non esplorato: quello della generazione automatica del codice, che elimina gran parte del lavoro pur conservando una libertà assoluta di customizzazione (come nell’ultimo caso).

Arrivare alla generazione automatica del codice ha un costo e non è detto che paghi sempre. Questi i contesti dove secondo me la generazione automatica paga:

  • UI che gestiscono varie entità in modo per lo più omogeneo
  • workflow che gestiscono varie entità in modo per lo più omogeneo
  • mapping tra entità (invece di utilizzare automapper)
  • codice collante strutturale (flusso application-domain-repository per una certa entity)
  • unit test che seguono un certo standard e certi input limite noti
  • entità e metodi derivati da sorgenti esterne (database, wsdl, xsd, api REST)
  • documentazione dei metodi per soddisfare determinati standard
  • refactoring complessi automatizzabili

Altri casi sono facilmente individuabili: ogni qualvolta ci troviamo a lavorare “come macchine” dovremmo far fare il lavoro “alle macchine” per lasciare a noi i lavori più interessanti.

Buon riuso! Anzi, buon riuso+automazione…!

Posted in pattern | No Comments »

Evoluzione dei test – Debugger, TDD, BDD, LINQPad

Posted by Ricibald on June 24th, 2013

Uno strumento fondamentale per sviluppare in .NET si sta sempre più rilevando LINQPad.

Nonostante sia nato per analizzare le query prodotte da LINQ, di fatto lo strumento è molto di più: consente infatti di testare al volo porzioni di codice .NET.

Facciamo subito un esempio pratico. Immaginiamo di avere un codice 3-layer con diversi componenti remoti che interagiscono tra di loro mediante protocolli più o meno complessi. Uno di questi componenti deve validare l’indirizzo mail che arriva in input da uno degli altri componenti. Il codice che validerà la mail è il seguente:

Regex.Match(emailAddress, @"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$");

Immaginiamo di voler testare questo codice. Come faresti?

Come verifichiamo il nostro codice? Vecchio stile…

In uno sviluppo classico (errato) si procede in questo modo:

  1. si scrive il codice fino a ottenere l’elaborato finale
  2. si testa il codice facendo girare tutti i vari componenti e incrociando le dita… se va tutto bene, bene… sennò si collega il debugger di VS e si passa per giorni e giorni di debugging…

Questo approccio ha tanti limiti tra cui: dipendenza da componenti esterni, tempi tecnici lunghi, non ripetibilità automatica del test.

In uno sviluppo più evoluto (TDD) si farebbe uso di unit test come segue:

  1. si scrive prima il metodo di test che verifica che a fronte di mail corrette non abbiamo errori e che viceversa a fronte di mail errate avremo eccezioni
    • il test dovrà essere isolato e atomico iniettando mock o, meglio, stub
  2. si scrive il minimo codice possibile per far compilare il codice
  3. si esegue il test, che deve fallire (il comportamento non è ancora implementato)
  4. si scrive l’implementazione vera e propria del test
  5. si riesegue il test, che stavolta dovrà andare bene

Questo approccio corregge i limiti sopra esposti consentendo una ripetibilità dei test e un isolamento dei componenti.

Gli unit test sono la risposta allora… Quale è il problema?

Gli unit test sono il modo di procedere corretto ma richiede una competenza di alto livello:

  • bisogna conoscere framework di dependency injection, unit test, mocking
  • bisogna conoscere bene i confini di un test: non bisogna testare né troppo né poco
  • gli input dei test devono essere significativi per verificare i “casi limite”
  • richiedono molto rigore: a ogni bug rilevato bisognerebbe creare il test corrispondente e fixarlo
  • bisogna saper isolare molto bene i test e rifattorizzarli nei punti variabili per evitare che una modifica nel codice comporti una modifica a cascata di tutti i test collegati

Oltre alle competenze richieste, i test di fatto aumentano comunque il lavoro complessivo:

  • bisogna scrivere test e mock per tutti gli input significativi
  • bisogna rifattorizzare i test e mantenerli nel tempo a fronte di cambiamenti anche strutturali

Non sto dicendo non bisogna fare unit test, anzi. Il problema è che una competenza simile è difficile trovarla ed è complicato trovare un progetto con un contesto culturale favorevole a un approccio di questo tipo.

Gli unit test sono troppo complessi…? Allora testiamo solo gli use case…

Allora era giusto il precedente approccio? Torniamo al debbugger con VS? Non credo sia corretto tornare nella propria zona di comfort, l’ideale sarebbe crearsi la competenza per perseguire gli unit test “puri”. Ma una via di mezzo potrebbe comunque esistere.

Si può semplificare e non scrivere 100 test in isolamento arrivando a una copertura del 100% del codice testato, bensì scrivere solo test “integrati” che vadano a verificare end-to-end il comportamento del codice integrato. Questo assomiglia più al BDD (Behavior-driven development) e presenta i seguenti vantaggi:

  • si verificano le porzioni di codice che effettivamente verranno eseguite nei vari casi d’uso
  • non richiede un’infrastruttura di stub/mock: si possono anche non conoscere framework di dependency injection e mocking

Il problema è che comunque i test devono essere atomici: l’esito non deve essere influenzato da altri test. Significa che siamo costretti a creare nel db e/o componenti dipendenti tutte le precondizioni che servono per avere una situazione “pulita” da testare.

Il BDD è ottimo per avere test che verifichino il giro completo del codice in modo ripetibile e quindi automatizzabile. Ma il BDD non è efficace per il nostro semplice caso di test di esempio. Se vogliamo solo testare se l’espressione regolare è valida per un’indirizzo email dovremmo porci in troppe precondizioni per poi fare semplici asserzioni.

 Gli use case sono troppo complessi…? Compilo ed eseguo al volo…

Un approccio estremamente più semplice e immediato per verificare il codice potrebbe essere quello di crearsi una Console Application, copiare/incollare il codice e testare il codice dentro la console.

Questo ha però dei tempi tecnici necessari come creare la solution, compilare e andare in debug. Questo comporta una risposta psicologica negativa: il test si fa solo quando serve veramente. Il vantaggio ci sarebbe ma per esperienza, nonostante sia il modo più immediato, nessuno lo fa: ci sarà o no un motivo…?

Un test al volo è troppo macchinoso…? Viene in aiuto LINQPad!

Siamo finalmente arrivati al nostro incredibile “silver bullet”. LINQPad, oltre a verificare le query LINQ generate, consente di ispezionare il risultato di un qualunque snippet di codice .NET compilandolo “al volo” tramite CSharpCodeProvider.

Lo screenshot seguente mostra, nello scenario di test presentato all’inizio, un test “al volo” della validazione della mail in questione:

Expression

Abbiamo quindi “cablato” il test verificando che con email “test@gmail.com” il metodo Regex.Match restituisce Success == true. Possiamo inoltre navigare il risultato: ad esempio possiamo ispezionare la collezione Groups, ottenendo i relativi gruppi in modo molto semplice:
Navigate

Volendo potremmo immergere il test in più input significativi creando una piccola procedura come segue:
Program

Se il codice che stiamo copiando o incollando fa uso di librerie esterne (create da noi o scaricate) possiamo includerle in modo da farle riconoscere dal compilatore.

Nell’esempio precedente si nota l’extension method Dump che consente di mostrare a video il contenuto di una qualunque struttura consentone una semplice navigazione tra strutture complesse. Prendiamo come esempio un Dictionary… in LINQPad tramite Dump lo visualizzereste in questo modo, direi piuttosto comodo, no…??
Dictionary

Uso di LINQPad

LINQPad si presta benissimo ai seguenti usi:

  • test al volo di nostro codice copiato/incollato da VS
  • test al volo di API .NET come LINQ, PLINQ, RX, …
  • test degli stati intermedi del chaining (qui un approfondimento)
  • apprendimento tramite esperimenti di librerie del framework .NET o di terze parti scaricate tramite NuGet
  • ispezione e navigazione di strutture e relazioni
  • navigazione del database senza passare per continue JOIN
  • analisi del database da un più alto livello di astrazione
    • grazie a ORM supportati come EF
    • grazie a provider supportati come MSCRM, Sharepoint, Azure, DataMarket, OData, StreamInsight, …
  • utility di uso comune tramite extension method (qui alcuni extension method di terze parti)
    • query LINQ che generano file CSV
    • query LINQ che generano SQL complessi da inviare via mail

Prossimi passi…??

Questi i prossimi passi per guadagnare la cintura marrone in LINQPad:

  1. Scarica LINQPad
  2. Scrivi il tuo codice normalmente in Visual Studio
  3. Appena terminato un metodo, anche semplice, copialo in LINQPad
    1. Se il tuo metodo fa uso di strutture esterne copiale direttamente o, se troppe, includi la dll
  4. Esegui su un input di esempio e ispeziona tramite Dump che tutto sia ok
    1. Se necessario verifica anche i tempi di esecuzione riportati
    2. Se necessario salva il codice per un futuro uso nella cartella “My Queries
  5. Rendila un’abitudine nel tuo lavoro quotidiano

Se veramente diventa un’abitudine eviterai il 90% degli errori, abbattendo ore noiose e degradanti di debugging…

Questi i passi invece per guadagnare la cintura nera in LINQPad:

  1. nella posizione dove di solito apri SQL Server Management Studio, rimpiazzalo con LINQPad
  2. apri sempre LINQPad al suo posto e fai le query solo utilizzando LINQ
  3. dopo un periodo di iniziale lentezza rispetto a SSMS scoprine i vantaggi
  4. non eseguire più join… limitati a seguire i link
  5. non ripetere più le stesse query… crea extension method riusabili
  6. non ipotizzare le query LINQ prodotte… verifica il SQL e prendine consapevolezza

Sperimenta nuove API con LINQPad. Pronti per lo step??

Posted in .net, test | No Comments »

WCF Client: “Using” best practices

Posted by Ricibald on March 15th, 2013

According to this official Microsoft link you should not use “using” to dispose your wcf client.

Instead use this extension method:

namespace System.ServiceModel
{
    public static class Extensions
    {
        /// <summary>
        /// Release safely your WCF Client
        /// </summary>
        public static void UsingSafe<T>(this T client, Action<T> work)
            where T : ICommunicationObject
        {
            try
            {
                work(client);
            }
            finally
            {
                try
                {
                    client.Close();
                }
                catch (CommunicationException)
                {
                    client.Abort();
                }
                catch (TimeoutException)
                {
                    client.Abort();
                }
                catch (Exception)
                {
                    client.Abort();
                    throw;
                }
            }
        }
    }
}

Usage:

new SomeClient().UsingSafe(channel => {
    channel.Login(username, password);
});

Posted in .net, wcf | No Comments »

Ninject: Replace without unbind

Posted by Ricibald on August 10th, 2012

In Ninject the method Rebind<T> does the following:

  • Unbind<T>: removes all binding for that types, also named binding!
  • Bind<T>: add the specified binding

This means that using Rebind<T>().To<U>().Named(“X”) you are not just replacing the binding named “X” but you are clearing all existing binding registered with T!

If you want to just replace it just use this:

Bind<T>().To<U>.Named("X").ReplaceExisting();

 

Here the source code to achieve this (works in Ninject 2+):
 

using System.Linq;
using Ninject.Planning.Bindings;
using Ninject.Syntax;

// ReSharper disable CheckNamespace
namespace System
// ReSharper restore CheckNamespace
{
    public static class ExtensionsNinject
    {
        /// <summary>
        /// Replace existing binding.
        /// To replace a binding you should never use rebind becauses unbind all existing
        /// binds and then bind yours.
        /// You should first configure the entire binding using Bind and only as last 
        /// operation you should declare to replace it using this method.
        /// </summary>
        public static void ReplaceExisting<T>(this IBindingInSyntax<T> bindingInSyntax)
        {
            ReplaceExistingImpl<T>(bindingInSyntax);
        }

        /// <summary>
        /// Replace existing binding.
        /// To replace a binding you should never use rebind becauses unbind all existing
        /// binds and then bind yours.
        /// You should first configure the entire binding using Bind and only as last 
        /// operation you should declare to replace it using this method.
        /// </summary>
        public static void ReplaceExisting<T>(this IBindingOnSyntax<T> bindingInSyntax)
        {
            ReplaceExistingImpl<T>(bindingInSyntax);
        }

        /// <summary>
        /// Replace existing binding.
        /// To replace a binding you should never use rebind becauses unbind all existing
        /// binds and then bind yours.
        /// You should first configure the entire binding using Bind and only as last 
        /// operation you should declare to replace it using this method.
        /// </summary>
        public static void ReplaceExisting<T>(this IBindingWhenSyntax<T> bindingInSyntax)
        {
            ReplaceExistingImpl<T>(bindingInSyntax);
        }

        private static void ReplaceExistingImpl<T>(IBindingSyntax bindingInSyntax)
        {
            var kernel = bindingInSyntax.Kernel;
            var bindingsToRemove = kernel.GetBindings(typeof(T)).Where(b => string.Equals(b.Metadata.Name, bindingInSyntax.BindingConfiguration.Metadata.Name, StringComparison.Ordinal));
            foreach (var bindingToRemove in bindingsToRemove)
            {
                kernel.RemoveBinding(bindingToRemove);
            }
            
            var binding = new Binding(typeof(T), bindingInSyntax.BindingConfiguration);
            kernel.AddBinding(binding);
        }
    }
}

Posted in ninject | No Comments »

NHibernate – Paging by root entity with eager join fetch of a child collection

Posted by Ricibald on July 15th, 2012

With nhibernate we can fetch entities using the fetch strategies explained in the link.

Now we consider only the use of fetching by join.

Scenario: I want to fetch by join the first 5 students with all the exams eagerly loaded.

If I write the QueryOver I end not with 5 results but with 100 results, almost all of these duplicated!

Why does this happen? The response is: count the rows! If you execute in SQL Server the query you ends with 5 results combinated with the corresponding exams. If every student has 20 exam, you ends with 100 students!

A simple solution: change fetch strategy to select. But if you want join fetch to overcame to N+1 problem you should use the following fixes:

You can merge duplicates by setting a DistinctRootEntityResultTransformer in the QueryOver, but merging them means that you obtain just the merged result of the first 5 rows: a single student!

To obtain all the students you should first create a query with none eagerly loaded, and then use this query as subquery to obtain the remaining references to eagerly loaded.

You can follow this example:

                // this will hold the criterial for the query
                var subQuery = QueryOver.Of<Parent>();

               // we build the criteria here...

               // add paging id projection so we only get one page of ids
                var pageSubQuery = subQuery.Clone()
                    .OrderBy(p => p.Id).Asc
                    .Select(p => p.Id)
                    .Skip(index ?? 0)
                    .Take(itemsPerPage ?? 20)
                    ;

                var items = session.QueryOver<Parent>()
                    .WithSubquery.WhereProperty(p => p.Id).In(pageSubQuery)
                    .OrderBy(p => p.Id).Asc // important to have the same order as above!
                    .Fetch(p => p.Children).Eager
                    .TransformUsing(new DistinctRootEntityResultTransformer())
                    .Future()
                    ;

                // Count
                var count = subQuery.GetExecutableQueryOver(session)
                    .Select(Projections.CountDistinct<Parent>(p => p.Id))
                    .FutureValue<int>();

Other solutions from the official post in nhforge.

Posted in .net | No Comments »

ASP.NET MVC: Dropdown EditorTemplate from ViewModel Instance by Convention

Posted by Ricibald on June 2nd, 2012

Based on separation between ViewModel and View when you want to display a Dropdown you should configure allowedvalues for a certain type inside the ViewModel instead of the Controller or the View.

For this reason, after long searches, I decided to implement my own solution based on convention.

This is the ideally expected result:

    public class UserViewModel
    {
        // the enum type is already handled specializing the string template
        public AreaEnumType AreaId { get; set; }

        [MultivalueAllowed]
        public int? CityId { get; set; }

        public IEnumerable<SelectListItem> CityIdAllowedValues()
        {
            var cities = getCitiesByRegion(this.AreaId);
            foreach(var city in cities) {
                yield return new SelectListItem { Text = city.Text, Value = city.Id, Selected = this.CityId == city.Id };
            }
        }
    }

In other words:

if you have a property that is to view as a dropdown, just add the attribute MultivalueAllowed and implement an instance method using the convention PropNameAllowedValues: you can also access to every instance property inside it!!!

These are the files to modify to achieve this (I’m using extension methods, reflection, UIHintAttribute, EditorTemplates, Razor):

/********** MultivalueAllowedAttribute.cs **********/
    public class MultivalueAllowedAttribute : UIHintAttribute
    {
        public MultivalueAllowedAttribute(bool allValuesVisibleFromStart = false) 
            : base(getUiHintFromConfiguration(allValuesVisibleFromStart))
        {
        }
        private static string getUiHintFromConfiguration(bool allValuesVisibleFromStart)
        {
            return allValuesVisibleFromStart ? "Combobox" : "Dropdown";
        }
    }
/********** global.asax.cs **********/
protected override void OnApplicationStarted()
{
     ModelMetadataProviders.Current = new CustomMetadataProvider();
}
/********** CustomMetadataProvider.cs **********/
namespace MvcExtensions
{
    public class CustomMetadataProvider : DataAnnotationsModelMetadataProvider
    {
        protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
        {
            var modelMetadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);

            // add container instance
            if(modelAccessor != null && modelAccessor.Target != null)
            {
                var containerField = modelAccessor.Target.GetType().GetField("container");
                if(containerField != null)
                {
                    var containerValue = containerField.GetValue(modelAccessor.Target);
                    modelMetadata.SetContainerInstance(containerValue);
                }
            }

            return modelMetadata;
        }
    }
}

namespace System
{

    public static class ModelMetadataExtensions
    {
        private static void addSafe(ModelMetadata modelMetadata, string key, object value)
        {
            modelMetadata.AdditionalValues.Add(key, value);
        }

        private static T getSafe<T>(ModelMetadata modelMetadata, string key)
        {
            object value;
            if(modelMetadata.AdditionalValues.TryGetValue(key, out value))
                return (T)value;
            return default(T);
        }

        public static void SetContainerInstance(this ModelMetadata modelMetadata, object value)
        {
            addSafe(modelMetadata, "containerInstance", value);
        }

        public static object GetContainerInstance(this ModelMetadata modelMetadata)
        {
            return getSafe<object>(modelMetadata, "containerInstance");
        }
    }
}
/********** Views/Shared/EditorTemplates/Dropdown.cshtml **********/
@model System.Object

@if (ViewData.ModelMetadata.DisplayName != null)
{
    @Html.LabelForModel()
}
@Html.DropDownListByConvention("")
@Html.Description("", new { @class = "description" })
@Html.ValidationMessage("", null, new { @class = "ym-message" })
        /********** HtmlHelperExtensions.cs **********/
        public static MvcHtmlString DropDownListByConvention<TModel>(this HtmlHelper<TModel> htmlHelper, string expression)
        {
            var metadata = ModelMetadata.FromStringExpression(expression, htmlHelper.ViewData);
            var containerInstance = metadata.GetContainerInstance();
            var containerType = metadata.ContainerType;
            var items = containerInstance.GetAllowedValues(containerType, metadata.PropertyName);
            if (metadata.IsNullableValueType)
            {
                items = SingleEmptyItem.Concat(items);
            }

            return htmlHelper.DropDownList(expression, items);
        }

        public static IEnumerable<SelectListItem> GetAllowedValues(this object instance, Type instanceType, string propertyName)
        {
            var allowedValuesMethodName = propertyName + "AllowedValues";
            var allowedValuesMethod = instanceType.GetMethod(allowedValuesMethodName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

            if(allowedValuesMethod == null)
            {
                throw new Exception("Unable to find instance method " + instanceType.Name + "." + allowedValuesMethodName);
            }

            var result = allowedValuesMethod.Invoke(instance, null);
            return (IEnumerable<SelectListItem>)result;
        }

Posted in .net | 3 Comments »

Come salvare la buona progettazione da morte certa…

Posted by Ricibald on January 15th, 2012

Ormai è tantissimo che non pubblico più nulla su questo blog, e con un buon motivo… Ero alla ricerca di me stesso

Può sembrare uno scherzo, ma limitatamente all aspetto tecnologico è proprio così.

Dagli ultimi articoli che ho letto in questo periodo ho approfondito tantissime tecniche di progettazione e implementazione:

  • TDD (Nunit), utilizzabile anche con semplici js tramite divisione MVC
  • Mock e Stub (Moq, Moles)
  • IoC e DI (Unity, NInject)
  • AOP e Decorator/Proxy (PostSharp)
  • DDD (l’unico vero modo per non ottenere codice procedurale ma vero OOP)
  • Code-First: il codice regna, il database è solo un’implementazione della persistenza (Persistence Ignorance)
  • Principio “Tell Don’t Ask”
  • ALM (VS Team System, tracking, branching, …)
  • CQRS: separa comandi (cambiano stato) da query (leggono stato) per non avere effetti collaterali. Questo porta all’uso di eventi a livello di sistema e a nuovi scenari di scalabilità (vedi Azure e db NoSql)
  • Generic Specialization: Double-Dispatch, Visitor pattern
  • Design: confine tra utility (semplice da usare) ed entertainment (evocativa e figa)
  • AHP e Reti neurali per supportare la Teoria delle decisioni
  • Progressive Enhancement, unobtrusive javascript, preemptive fetching
  • Reactive programming: solo eventi, nessun multithreading
  • Agile programming: XP, Scrum, Pair programming
  • Design By Contract
  • Convention over Configuration

Ora, questi sono “solo” puntatori a tutto ciò che ho imparato. Sono tutti concetti importantissimi, ma più o meno tutti si basano sul fatto che il team sia estremamente affiatato e competente nella tecnologia e nella progettazione.

E da qui sono arrivato al punto contraddittorio:

non riuscirò, probabilmente mai, a mettere in pratica questi concetti in un sistema omogeneo dove i membri del team abbiano la piena coscienza di cosa si sta facendo.

Ora, immaginiamo anche di aver trovato 2-3 persone molto competenti che sanno applicare queste tematiche: questo non basterebbe comunque! Nuove persone arriveranno nei progetti, le competenze cambieranno, le persone stesse cambieranno e considereranno “meno rilevante” fare bene le cose, “basta che funziona“. Quindi bisogna chiedere a sé stessi:

vale veramente la pena approfondire in questo modo le proprie conoscenze?

La filosofia “basta che funziona” è in realtà molto più nobile di come la si dipinge, basti pensare allo slogan “it just works” dell’Apple: porta all’efficacia di un progetto.

La buona analisi/progettazione può essere vista come un “cruccio” dell’analista/tecnico, quando poi alla fine comanda sempre e solo il risultato finale, il “just works”. Allora perché preoccuparsi tanto, perché dedicare tempo allo studio di pattern di analisi e progettazione? Beh, molto semplice, in tutti questi discorsi del “just works” non abbiamo considerato la dimensione risorse:

con risorse infinite… tutto funziona!

Una buona progettazione porta a tre benefici fondamentali: la predicibilità, il riuso e la separazione delle responsabilità. Il riuso consente di non reinventare funzionalità già scritte e “mature”, evitando di sprecare tempo inutile in cose già fatte e rifatte, analizzate e testate; la predicibilità è un requisito fondamentale del riuso. La separazione delle responsabilità consente di ottenere alta coesione e basso accoppiamento, consente di limitare gli impatti di una modifica e di implementare funzionalità trasversali, come caching o security abilitandone il riuso e l’attivazione o disattivazione su richiesta.

Questi benefici agiscono sulle risorse necessarie: comportano un beneficio concreto in termini di tempo, persone, soldi richiesti. Il caching se implementato correttamente consente di acquistare meno server, il riuso consente di diminuire i tempi di sviluppo e i bug riscontrati. La predicibilità consente di commettere meno errori in quanto il codice è privo di effetti collaterali.

Quindi questo porta a dire una cosa fondamentale:

la progettazione non ha lo scopo di produrre un sistema che funziona, ma serve a realizzarlo con meno impiego di risorse (tempo, persone, soldi).

La buona progettazione consente quindi di ottenere l’efficienza di un progetto.

Quindi, dopo aver prima messo in discussione e in seguito ricostituito il concetto di progettazione conferendogli quindi una rinnovata dignità di esistere, torniamo alla domanda iniziale:

come fare in modo che le tecniche di buona progettazione siano usate nel tempo?

Non possiamo pretendere che tutti siano competenti, ma possiamo sfruttare a nostro vantaggio molte debolezze umane, tra cui l’estrema conservatività con cui lavora la maggior parte delle persone, che non si domanda i perché delle cose, “basta che funzionano”. Immaginiamo un framework perfetto, che consente di suddividere il progetto in blocchi funzionali ideali, come potrebbe essere (a meno di qualche problema) ASP.NET MVC 3. In questo caso anche il programmatore più inesperto non può esimersi dal realizzare codice scritto in quella forma, e qualunque altra forzatura richiedere troppo sforzo per essere implementata, da cui potremmo sfruttare la “debolezza dell’incompetente”.

Quindi, secondo il sottoscritto, la strategia vincente non è fare in modo che tutti abbiano competenze a questo livello, ma costruire un team dove un “senior architect” sia incaricato della stesura della progettazione e della separazione dei componenti. La “novità” dell’approccio sta nel fatto che i componenti orchestrati devono avere caratteristiche tali da impedire utilizzi impropri alterandone l’architettura. Ad esempio c’è una bella differenza tra esporre questo metodo:

void setUserStatus(string status);

e questo metodo:

void setUserStatus(UserStatus status);

Il primo è suscettibile a utilizzi impropri (potrei scrivere uno stato valido “Active” ma anche uno non valido “Ready”), il secondo non ha possibilità di utilizzi impropri (l’enumerato ha solo valori discreti). Se i metodi rispettono queste regole, se le classi che lo contengono hanno i membri incapsulati correttamente, se i metodi non facade sono visibili solo nell’ambito dei moduli che lo contengono, se si segue l’approccio Design-By-Contract e si validano precondizioni e postcondizioni, non sarà possibile dall’esterno ottenere comportamenti che violano i vincoli architetturali.

Se inoltre abbiniamo controlli di Code Analysis e di complessità ciclomatica minima possiamo fare in modo che anche l’implementazione del singolo metodo non faccia uso di funzioni sbagliate definite altrove. Ma il principio deve sempre essere lo stesso:

permettere anche a un tecnico non evoluto di integrarsi in un sistema complesso nel modo corretto, senza che questo possa compromettere l’architettura.

Diventa quindi fondamentale che il ruolo dell’architetto sia ben delineato e confinato e che tecnici meno competenti non si occupino di concetti architetturali.

Oltre a questo è fondamentale che i singoli tecnici meno esperti abbiano al tempo stesso la giusta motivazione (non sono macchine!) e quindi il ruolo dell’architetto è da una parte schermare da usi impropri, dall’altra quello di concedere la giusta autonomia di implementazione poiché ognuno ha il proprio stile. Questo serve a motivare dal punto di vista tecnico, mentre dal punto di vista degli obiettivi è importante che ogni persona si senta responsabile del proprio blocco funzionale in tempi in cui lui stesso si senta impegnato a rispettare. Ad esempio c’è una bella differenza tra il dire: “fai questo task prima possibile” o dire: “se sviluppi tutto questo use case dall’inizio alla fine, mi dici quando credi di finire?“. Questo responsabilizza le persone poiché le fa sentire parte di qualcosa e se qualcosa va male nel loro use case o sono in ritardo nella consegna stai tranquillo che faranno anche mezzanotte poiché si sentiranno responsabili della loro parte. Ovviamente il loro use case deve essere comunque sempre protetto da implementazioni improprie che alterano l’architettura, e qui torniamo al punto precedente!

E per ultimo, le funzioni di utilità: aldilà del framework che implementiamo, ci sono funzioni utility di uso comune che spesso mettiamo a fattor comune, ma la cui memoria si perde nel tempo. Come fare per forzarne l’uso? Inanzitutto l’uso si può “suggerire” mediante gli extension method, sarà l’IDE che ne suggerirà l’autocomplete. Ma per forzare realmente si dovranno implementare dei custom Code Analysis mediante strumenti come FxCop.

Sintetizzando, design, progettazione e tecniche di programmazione sono fondamentali per minimizzare le risorse necessarie a realizzare un progetto e ottenere efficienza oltre a efficacia (“it just works”). Ma tali caratteristiche non devono appartenere a tutti, come suggeriscono tutti i modelli agili, ma possono purtroppo appartenere solo a poche persone “sagge”, che avranno il compito di costruire un’infrastruttura atta a garantirne il corretto uso nel tempo, anche quando loro stessi avranno (finalmente) cambiato o costruito la loro società ideale.

Posted in analysis, design | 1 Comment »

Perché passare da Svn a Git

Posted by Ricibald on August 30th, 2011

Come al solito… articolo condensato per non perdere tempo…!

Perché scegliere Git rispetto agli altri controlli versione come Svn, Cvs, …? Di seguito un elenco delle cose che Git consente in più rispetto agli altri sistemi:

  1. git è distribuito: ogni client non ottiene l’ultima versione disponibile (come in Svn) ma un clone dell’intero repository con tutto lo storico. Questo abilita un uso completo offline di tutte le funzionalità (commit, diff, log, branch, merge, annotation) in modo istantaneo. Inoltre il sistema non avrà un Single Point of Failure poiché ogni client avrà il full backup del progetto. Infine si può articolare una struttura di workflow in cui si mantengono dei repository separati con diversi permessi di lettura/scrittura che vengono integrati in un workflow “gold” (si veda questo articolo) [in TFS strutturare in questo modo è possibile grazie a un uso corretto dei permessi e delle policy].
  2. branch semplici: creare un branch ed eseguire lo switch a un branch sono operazioni che impiegano qualcosa come 0.1 secondi. Tale velocità cambia l’aspetto psicologico del branch: diventa un’operazione comune per qualunque cosa su cui si lavora: ogni feature, idea, bugfix, senza essere online con la possibilità di annullare un branch e cambiare contesto quasi in modo istantaneo. Il merge inoltre è a 3 vie e riduce al minimo le probabilità di conflitti.
  3. commit organizzate per feature: a differenza di altri sistemi come Svn, in Git i file locali non vengono inviati direttamente nel repository ma passano prima per una staging area (o index) che consente di specificare nel dettaglio quali file (e quali porzioni di file) si andranno a committare, in modo da risolvere il problema della “copia di lavoro intricata” e mantenere ogni commit un evento con il preciso scopo di riportare i file modificati impattati dopo aver implementato una determinata feature. Questa separazione consente di eseguire ad esempio il merge solo di determinate feature, lasciandone indietro altre.
    Infatti Git viene definito un “change control” invece di un “version control”: invece di presentare il progetto linearmente (mentalità dell'”undo”) Git vede solo un manipolo di commit pronti per essere rimescolati o amalgamati insieme
  4. utile a te: spesso si sceglie di non usare Git poiché non si fa parte di un team numeroso. In realtà Git aiuta te, non il tuo team: il branch locale, il context switching, le commit come feature, aiutano l’individuo, non il team. Velocità e backup sono sempre una buona cosa, sia in team che non.
Ottimi articoli:

Posted in .net | 2 Comments »

Adapt/convert Microsoft Ajax events to JQuery

Posted by Ricibald on July 22nd, 2011

It’s very useful to express everything in JQuery instead of ASP.NET AJAX events system: in this way we can use a lot of useful JQuery controls.

To achieve this just add this snippet of javascript code:

<script type="text/javascript">
	Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequest);
	Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequest);
	function BeginRequest(sender, args) {
		jQuery.event.trigger('ajaxSend');		
	}
	function EndRequest(sender, args) {   
		jQuery.event.trigger('ajaxComplete');		                             
	}
</script>

In this way you can capture standard JQuery event to obtain for example a modal progress feedback both in case of JQuery ajax POST and in case of ASP.NET UpdatePanel events:

<script type="text/javascript">
	$(document).bind("ajaxSend", function () {
		$("#loadingAjax").dialog({ modal: true });
	}).bind("ajaxComplete", function () {
		$("#loadingAjax").dialog("close");
	});
</script>

Posted in asp.net, javascript, jQuery | No Comments »

iOS NIB Localization in Localizable.strings

Posted by Ricibald on June 3rd, 2011

Scenario:

I want to localize my app AllSync but I was taken by a little frustration.

Following this good guide you can see that there are two main way to localize your iOS (iPhone/iPad) app:

  • localize strings using Localizable.strings
  • localize single nib file creating one version for each
The second point is very frustrating for three reasons:
  • you have to mantain updated all version of your nib localized files
  • there are specialized sites like icanlocalize that translates only your Localizable.string, not your nib files
  • you have to take care about the resulting layout of single translation
The problem:
I want to localize my nib files in the same way of using Localizable.strings

A possible solution can be to externalize in code every text setting but is a tedious process and you can’t use the flexibility of xcode 4. The real solution I hope will be used by many of you is this:

The solution:

Create an extended version of iOS user control that automatically translates every single text

Simple to obtain: just see this extended UIButton

@interface UIButtonThemed : UIButton
@end

@implementation UIButtonThemed
- (id)initWithCoder:(NSCoder *)aDecoder {
    if ((self = [super initWithCoder:aDecoder]))
	{
        self.titleLabel.adjustsFontSizeToFitWidth = YES;
        NSString* text = NSLocalizedString(self.titleLabel.text, nil);
        [self setTitle:text forState:UIControlStateNormal];
        [self setTitle:text forState:UIControlStateHighlighted];
        [self setTitle:text forState:UIControlStateDisabled];
        [self setTitle:text forState:UIControlStateSelected];
	}
	return self;
}
@end

You can use it inside xcode 4 configuring the base class for your control:

Then you can see my italian Localizable.strings:
"Sync" = "Sincronizza";
"Settings" = "Impostazioni";
"Help" = "Guida";
"Share" = "Condividi";
"Rate us" = "Votaci";
"Follow us" = "Seguici";
And the corresponding result:

Posted in iphone, projects | 12 Comments »