PostSharp: CompileTimeValidate()
Un paio di giorni fa abbiamo visto come usare PostSharp per validare a runtime i parametri di un metodo (per inciso funziona anche con i costruttori) facendo semplicemente una cosa del genere:
class MyTestClass { public void Foo( [NotNull]String arg ) { Console.WriteLine( "Foo( String ): " + arg ); } }e producendo a runtime una ArgumentNullException se chiamiamo Foo() passando un valore null. Adesso immaginiamo di scrivere una cosa del genere:
class MyTestClass { public void Foo( [NotNull, Int32RangeValidator( CompareLogic = CompareLogicOperator.Greater, ReferenceValue = 0) ]Int32 arg ) { Console.WriteLine( "Foo( Int32 ): " + arg ); } }abbiamo un overload di Foo() che prende un intero e vogliamo che questo sia maggiore di 0 ma erroneamente, perchè Int32 è un value type, vogliamo anche che non sia null… compiliamo e:
Lasciatemi dire: semplicemente fantastico!
Il tutto è stato di una semplicità disarmante:
[Serializable] public class ArgumentValidatorAspect : OnMethodBoundaryAspect { public override bool CompileTimeValidate( MethodBase method ) { Boolean returnValue = true; method.GetParameters() .Where( pi => pi.IsAttributeDefined<NotNullAttribute>() ) .ForEach( pi => { if( pi.ParameterType.IsValueType ) { Message error = new Message( SeverityType.Error,PostSharp ha un motore di validazione che viene invocato a compile time e che ci permette di controllare, parzialmente, il processo di build eventualmente interrompendolo se non sono soddisfatti determinati requisiti, come nel nostro caso.
"RV0001",
"Cannot apply NotNullAttribute to a ValueType.",
method.Name ); MessageSource.MessageSink.Write( error ); returnValue = false; } } ); return returnValue; }
}
Questo apre a scenari notevoli, dimentichiamoci per un momento di tutto quello che PostSharp può fare a runtime e soffermiamoci solo sulla fase a compile time: la manna del programmatore sono gli errori del compilatore avere la possibilità di controllare il processo di build anche attraverso attributi custom/aspect è semplicemente potentissimo.
.m