Spring.NET
Rappresenta la modalità di intercettamento di un motodo e quindi la modalità di intruduzione del codice. I tipi di Advice sono quattro: AroundAdvice: implementa l'interfaccia IMethodInterceptor e permette il massimo controllo su un metodo dato che possiamo aggiungere logica primo e dopo l'invocazione del metodo target. Questo è l'Advice più potente ma anche il più richioso, dato che possiamo dimenticare di chiamare il metodo Proceed() che rappresenta l'invocazione del metodo target. BeforAdvice: implementa l'interfaccia IBeforAdvice e permette di introdurre codice soltanto prima dell'invocazione del metodo target. AfterReturningAdvice: implementa...
Un Pointcut definisce una regola di individuazione di un Joinpoint. Spring.NET offre diverse implementazioni di Pointcut, forniti come moduli indipendendi, implementati come singole entità in modo da renderli riutilizzabili ed intersecabili per diversi Advice. Ogni Pointcut implementa l'interfaccia IPointcut, la quale tramite i due membri ITypeFilter e IMethodMatcher permette di filtrare in base al tipo ed alla firma del metodo. Nella maggior parte dei casi le implementazioni dei Pointcut sono gestite in maniera statica (StaticPointcut), in modo da effettuare il caching del risultato di una valutazione di matching (operazione costosa in termini di performance) la prima volta che...
Altra parte fondamentale di Spring.NET è l' AOP Framework. Questo post non vuole spiegare che cosa è o non è l'AOP, ma vuole focalizzarsi soltanto su gli strumenti forniti da Spring.NET per utilizzare questo paradigma di programmazione nelle nostre applicazioni .NET. Tutta via, un minimo di infarinatura è obbligatoria, in poche pareloe l'Aspect Oriented Programming è un paradigma complementare all'Object Oriend Programming e permette di modularizzare gli aspetti ed i comportamenti trasversali della nostra applicazione, separandoli dal dominio applicativo. L' AOP è composta da i senguenti concetti non legati al framework utilizzato ma al paradigma stesso: ...
Spring.NET grazie alla classe ObjectDefinitionBuilder espone delle flunt interface API che permettono di definire oggetti da registrare nell' ApplicationContext. Per mostrare questa funzionalità non documentata replicherò l'esempio mostrato nel post [Spring.NET #14] Spring.Core, IoC e DI (Setter Injection) : 1: using System;
2: using Spring.Context.Support;
3: using Spring.Objects.Factory.Support;
4:
5: namespace SpringSeries.Core.ObjectDefinitionBuilderFluentInterface
6: {
...
Grazie al motore di IoC, Spring.NET offre la funzionalità di Loosely Coupled Event Wiring, vale a dire la possibilità di scatenare ed intercettare eventi senza un legame diretto fra il publisher ed il subscriber. Il meccanismo avviene grazie ad un Registry mantenuto da Spring.NET, dentro al quale il publisher registra i propri aventi, rendendoli pubblici, a questo punto il subscriber potrà "dire" a Spring.NET quale eventi sottoscrivere. Passiamo subito ad un esempio pratico, creiamo una ConsoleApplication ed aggiungiamo la reference a Spring.Core.dll. Procediamo con l'oggetto publisher, come prima cosa aggiungiamo una classe CustomEventArgs, la quale sarà utilizzata nell'evento scatenato dalla...
Il framework di supporto per le WinForms si chiama Spring.NET RichClient ed è un progetto disponibile a parte rispetto a Spring.NET, sviluppato da Harald Radi. Ad oggi l'ultima versione scaricabile dal sito, la 0.2.1, è un po vecchiotta e presenta diversi problemi, quindi vi consiglio di scaricare l'ultima versione del codice sorgente direttamente dal trunk. Anche in questo questo post mi limiterò a parlare solo dell'integrazione fra le WinFroms ed il Validation Framework, altri aspetti riguardanti le applicazioni Windows e Spring.NET verrànno trattati in post futuri. Finite queste precisazioni iniziamo creando un'applicazione Windows ed aggiungendo i riferimenti alle librerie Spring.Core...
In questo post affronteremo l'integrazione del Validation Framework di Spring.NET con le WebForm di ASP.NET. L'integrazione di Spring.NET con ASP.NET è molto ampia e non tocca solo il discorso della validazione, però in questo post mi limiterò su questo argomento. Fatta questa premessa cominciamo creando in Visual Studio un nuovo progetto ASP.NET Web Application, aggiungiamo le classi Person, AnddressInfo utilizzate nei post precedenti. Facciamo uguale con il file di risorsa Message.resx (introdotto in questo post), aggiungendolo nella directory App_GlobalResources. Eliminiamo Default.aspx ed aggiungiamo le pagine PersonEdit.aspx e...
Altro nodo molto importante del Validation Framework sono le Validator Actions, le quali permettono di eseguire un operazione come consequenza del risultato della validazione. Lo scenario più frequente è quello di utilizzare una Error Message Actions per aggiugre un messaggio di errore alla collezione degli errori, gestita da Spring.NET. Nell'esempio mostrato nel primo post sul Validation Framework ho volutamente omesso questa parte per far capire meglio le due fasi distinte del processo di validazione, la prima dove vengono applicate le regole e la seconda dove vengono eseguite una serie di operazioni di conseguenza. Come intuibile la seconda fase è dipendente...
Come già detto in un post precedente possiamo definire il set di regole di validazione anche in maniera programmatica utilizzando le API fornite da Spring.NET. Vediamo come creare via codice le regole dichiarate nel file XML nell'esempio del post precedente: 1: using System;
2: using Spring.Validation;
3: using Spring.Expressions;
4:
5: namespace SpringSeries.Core.ValidationObjectModel {
...
La validazione di un'oggetto avviene grazie alla definizione di un insieme di regole. In Spring.NET la singola regola si chiama Validator e l'insieme di regole si chiama Validator Groups. Come è facile immaginare esistono già built-in diversi tipi di Validators e di Validator Groups adatti ai più disparati scenari di validazione però se in certi casi non sono adatti ai nostri bisogni possiamo sempre crearne di nostri implementando l'interfaccia IValidator oppure la classe base BaseValidator. Analiziamo i Validators cominciando dal più semplice, il Required Validator, il quale verifica che un determinato campo sia valorizzato: <v:required id="PersonFirstNameValidator" test="FirstName" />
procediamo...
Iniziamo a parlare del Validation Framework contenuto in Spring.NET, un framework molto completo e varsatile adatto a molti scenari. I motivi che hanno spinto il team di Spring.NET ha creare questo framework sono svariati, descritti dettagliatamente in qui e qui. Il più grande problema della maggior parte dei framework di validazione disponibili oggi è che sono troppo legati alla tecnologia di presentazione, come le stesse funzionalità di validazione fornite dal .NET Framework per ASP.NET e WinForm. Grazie a Spring.NET possiamo effettuare la validazione dei dati non più solo nel presentation layer ma in tutti i layer che compongono la nostra...
Nel post precedente ho parlato dell'interfaccia IMessageSource e della sua implementazione più semplice, StaticMessageSource. In questo post invece vedremo la più utile implementazione ResourceSetMessageSource, la quale permette di leggere le risorse in maniera localizzata da file .resx direttamente con l' ApplicationContext, definendo il funzionamento tramite il file di configurazione. Come di consueto creiamo una Console Application ed in seguito aggiungiamo due file di risorse di nome AppRescource.resx ed AppResource.en-US.resx, nel primo inseriamo, utilizzando come chiave la stringa "HelloMessage", la frase localizzata in italiano, nel secondo invece, sempre con la solita chiave, inseriamo la frase localizzagta in inglese. Adesso aggiungendo un...
Spring.NET offre anche funzionalità di localizzazione/internazionalizzazione delle risorse. Tutta la gestione avviene tramite l'interfaccia IMessageSource, che è parte integrante dell' ApplicationContext, con i seguenti metodi: GetMessage: esistono molti overload di questo metodo i quali permettono di ottenere una risorsa di tipo stringa indicando la chiave, la CultureInfo, ed un'insieme di argomenti che verranno utilizzati come valori di replace per la stringa. GetResourceObject: permette di ottenere una quasiasi risorsa, per esempio un immagine. Anche in questo caso esistono più overload del metodo ed i possibili parametri sono la chiave, la CultureInfo. ...
Ieri è stata rilasciata la versione finale di Spring .NET 1.1 . Potete effettuare il download da SourceForge, leggere il dettagliato changelog oppure la nuova documentazione. Colgo l'occasione per ricordarvi che Spring.NET è un software Open Source che offre un supporto commerciale tramite l'azienda SpringSource. Technorati Tag: Spring.NET
Expression Language è un linguaggio di interrogazione e manipolazione di grafi di oggetti. Questa funzionalità è molto utile in tutti quei casi di verifica dello stato di un oggetto a runtime. Spring.NET utilizza questo linguaggio per l' IoC Container, Data Validation ed il Data Binding per ASP.NET. Questo linguaggio utilizza la libreria ANTLR per costruire il Lexer ed il Parser dell'espressione. Tutta la grammatica utilizzabile all'interno di una espresione è definita nel file Expression.g . Facciamo subito un esempio per capiere meglio di cosa parliamo, all' interno una Console Application aggiungiamo una classe Student: 1: using System; 2: ...
Oggi parlerò delle funzionalità di Object Pooling esposte da Spring.NET, la spiegazione di questo pattern esula dallo scopo del post quindi per maggiori informazioni vi rimando a questo link: Object Pooling Pattern. Il namespace Spring.Pool espone due interfacce che permettono di creare un pool di qualsiasi oggetto: IPoolableObjectFactory: definisce i metodi per la gestione del lifecycle dell'oggetto che sarà utilizzato nel pool. IObjectPool: definisce i metodi per utilizzare e monitorizzare il pool di oggetti ed utilizza l'interfaccia sopra citata per istanziare gli oggetti del pool. Inoltre Spring.NET tramite la classe SimplePool offre una semplice implementazione dell'interfaccia IObjectPool. Vediamo come sfruttare...
La sincronizzazione dell'accesso alle risorse in ambiente multi-thread viene gestito tramite interfaccia ISync, composta da tre metodi: Acquire: ottiene il lock sulla risorsa desiderata. Release: rilascia il lock precedentemente acquisito. Attempt: ottiene il lock sulla risorsa desidera per un tempo massimo espresso in millisecondi, al termine del quale viene automaticamente rilasciato il lock. Spring.NET offre due implementazione della suddetta interfaccia: Latch: rappresenta una condizione booleana. Questa classe viene tipicamente utilizzata per "dare" il segnale di partenza ad un gruppo di thread. Semaphore: rappresenta l'implementazione di un semaforo. Questa classe viene tipicamente utilizzata per limitare il numero...
Cominciamo a scoprire il supporto che Spring.NET offre nel campo delle applicazioni asincrone. Nonostante la Base Class Library fornisca già un vasto insieme di classi per il Multi-threading il team di Spring.NET anche in questo caso ha introdotto una serie di classi che permettono di lavorare con una maggiore astrazione ed in più offrono funzionalità assenti nelle versioni precedenti alla 2.0 del .NET Framework come il Semaphore . La prima parte che analizziamo riguarda il thread local storage, il quale cambia a seconda del tipo di applicazione che stiamo sviluppando, infatti se ci troviamo in un contesto Web useremo la classe System.Web.HttpContext.Current...
Il Core di Spring.NET offre, tramite l'interfaccia IResource, la possibilità di accedere a diverse tipologie di risorse in maniera polimorfica ed indipendente. Grazie a questa inferfaccia possiamo accedere ad un file di testo o ad un assembly nella stessa modalità. Per caricare le risorse possiamo utilizzare una implementazione dell'interfaccia IResourceLoader oppure nella maniera più pratica e veloce utilizzando il metodo GetResource dell'interfaccia IApplicationContext. La localizzazione della risorsa avviene trame URI (Uniform Resource Identifier), Spring.NET fornisce un insieme di schema aggiuntivi rispetto a quelli forniti dal .NET Framework tramite la classe URI, l'elenco completo è consultabile a questa pagina Built-in IResource implementations. Passiamo subito alla pratica creando...
E' stato pubblicato oggi su ARCast.TV il video-intervista fatta a Mark Pollack (fondatore di Spring.NET) durante il Tech-Ed. Infatti ci tengo a ricordare che è la prima volta al Tech-Ed viene presentato un Framework Open Source e che i "ragazzi" di Spring.NET hanno tenuto due sessioni, sul forum è possibile leggere l'abstract. Spring is a popular Java framework for building applications that Mark Pollack had become quite familiar with. However he wanted to write applications in .NET so Spring.NET was born. In this episode I caught up with Mark at Tech-Ed US where we told me all about it. Trovate il video...
Il .NET Framework per convertire un oggetto da un tipo ad un'altro utilizza i TypeConverter. Lo stesso sistema viene utilizzato da Spring.NET per convertire i valori stringa inseriti nel file di configurazione in tipi concreti. Il framework Spring.NET fornisce già un'insieme di custom TypeConverter (a questa pagina potete trovare l'elenco completo) come il FileInfoConvert che serve a convertire una stringa in una istanza di System.IO.FileInfo. Se abbiamo la necessità possiamo creare un nostro custom TypeConverter, per maggiori informazioni leggete questo articolo How to: Implement a Type Converter. Come esempio modifichiamo la classe Person vista in alcuni post precedenti aggiungendo un riferimento ad una nuova calsse AddressInfo: ...
In questo post vediamo come applicare alla classe PhraseTranslator un banale sistema di log. Itroduciamo una nuova interfaccia che farà da contratto per le varie implementazioni di log (es: Console, File di testo): 1: public interface ITranslatorLog 2: { 3: void LogTranslation(string phraseToTranslate, string phraseTranslated); 4: }
come prima cosa creiamo un NullTranslatorLog applicando il pattern NullObject, il quale farà da default logger per la classe PhraseTranslator:
1: public sealed class NullTranslatorLog : ITranslatorLog 2: { 3: public void...
Grazie alle funzionalità di Constructor Argument Resolution viste nei post precedenti Spring.NET implementa l' IoC di tipo 3 (Constructor Injection). Iniziamo estendendo la classe per tradurre frasi dall'inglese all'italiano in modo che supporti altri linguaggi, per fare questo applichiamo il Design Pattern Strategy. Creiamo l'interfaccia ITranslator la quale rappresenta il contratto: 1: public interface ITranslator 2: { 3: string Translate(string phraseToTranslate); 4: }
procediamo implementando le classi che si occuperanno realmente di tradurre la frase, ne facciamo una dall'inglese all'italiano:
1: public class EnglishToItalianTranslator : ITranslator 2: { ...
Grazie a Spring.NET possiamo settare le proprietà di un oggetto al momento della sua creazione sempre tramite il file di configurazione, basterà impostare il tag <property/>. Modifichiamo la classe Person dei post precedenti eliminando il costruttore parametrico e modifichiamo il file .config così:<object id="Matteo"
type="SpringSeries.Core.SettingProperties.Person, 10.SettingProperties">
<property name="FirstName" value="Matteo" />
<property name="Age" value="24" />
</object>
rispetto alla valorizzazzione dei parametri del costruttore in questo caso abbiamo a disposizione solo il Name Matching. Utilizzando il tag <null/> all'interno di <property/> possiamo impostare una proprietà a null. Per esempio supponiamo che Age...
Oggi un mio amico mi ha chiesto se è possibile valorizzare a run-time i parametri di un costruttore invece di usare il file di configurazione. Certo che si può fare! Basta definire il nostro oggetto con un qualsiasi tipo di matching visti nei post precedenti ed in fine istanziare la classe utilizzando un particolare overload del metodo GetObject, il quale accentta in ingresso un array di object contenente i valori da passare al costruttore. Quindi il file di configurazione rimane invariato:<object id="Matteo"
type="SpringSeries.Core.RuntimeMatching.Person, 09.RuntimeMatching">
<constructor-arg name="firstName"...
In questo post vedremo l'ultima modalità di matching dei parametri, il Name Matching. Come negli episodi precedenti per istanziare la classe Person basterà effettuare una piccola modifca ai tag constructor-arg :<object id="Matteo"
type="SpringSeries.Core.NameMatching.Person, 08.NameMatching">
<constructor-arg name="firstName" value="Matteo" />
<constructor-arg name="age" value="24" />
</object>
Technorati Tags: Spring.NET
Nel post precedente abbiamo visto come istanziare una classe con il costruttore parametrico utilizzando il Type Matching adesso vedremo come istanziare la solita classe utilizzando la modalità di Index Matching. Per farlo modificheremo il file di configurazione così:<object id="Matteo"
type="SpringSeries.Core.IndexMatching.Person, 07.IndexMatching">
<constructor-arg index="0" value="Matteo" />
<constructor-arg index="1" value="24" />
</object>
come vedete basta indicare l'indice zero-based della posizione del parametro all'interno della firma del costruttore.
Technorati Tags: Spring.NET
In un post precedente abbiamo visto come instanziare un oggetto tramite il suo costruttore di default, quindi privo di paremetri, con Spring.NET possiamo anche creare oggetti che hanno un costruttore parametrico. La particolarietà sta nel fatto che possiamo valorizzare i parametri direttamente nel file di configurazione. Supponiamo di avere una classe Person definità così: 1: public class Person 2: { 3: private string _firstName; 4: private short _age; 5: 6: public string FirstName ...
Gli oggetti creati con Spring.NET possono avere due tipi di visibilità e ciclo di vita: Singleton e Prototype (non-singleton). Quando impostiamo la creazione di un oggetto nella prima modalità indichiamo a Spring.NET che noi vogliamo utilizzare un unica istanza di esso condivisa per tutto il ciclo di vita dell'applicazione, quindi la prima volta che richiamiamo l'oggetto tramite il suo id esso viene creato e le volte successive viene restituita sempre la solita istanza. L' altra modalità invece indica a Spring.NET che ad ogni richiesta deve essere creata una nuova istanza dell' oggetto, quindi il suo ciclo di vita sarà gestito...
Per rendere il file di configurazione più leggibile Spring.NET ha una funzionalità chiamata Type Aliases, la quale permette di attribuire un nome ad un tipo. Nel post precedente, abbiamo visto la difficolta di lettura della definizione di una collection Dictionary<string,<Dictionary<int,object>>, addesso definiamola utilizzando gli aliases. Prima di tutto dobbiamo aggiungere il relativo configuration handler al section group di Spring.NET, il quale risulterà così:<configSections>
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
<section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
<section name="typeAliases" type="Spring.Context.Support.TypeAliasesSectionHandler, Spring.Core"/>
</sectionGroup>
</configSections>
in seguito possiamo definire i nostri aliases all'interno dell' apposito tag:<typeAliases>
<alias name="NestedDictionary" type="System.Collections.Generic.Dictionary<int,object>"/>
...
Spring.NET è basato sulla versione 2.0 del .NET Framework quindi permette l' utilizzo dei generics. Vediamo subito un paio di esempi per capire la sintassi, cominciamo dichiarando e creando una semplice lista di interi:
<object id="ListInteger" type="System.Collections.Generic.List<int>" />
per istanziare la collection utilizzeremo questa riga di codice:
List<int> _col1 = (List<int>)_ctx.GetObject("ListInteger");
adesso dichiariamo una collection Dictionay con il tipo chiave string e il tipo valore object:
<object id="DictionaryStringObject" type="System.Collections.Generic.Dictionary<string,object>" />
di seguito...
Spesso nel nostro codice per creare un oggetto utilizziamo un semplice metodo statico (Factory Method) che si occupa di fare la new dell'oggetto interessato. In questo caso possiamo "dire" a Spring.NET di utilizzare il metodo factory per la creazione dell'oggetto desiderato, vediamo come fare. Per prima cosa aggiungiamo alla classe del post precedente il seguente metodo factory:public static EnglishToItalianTranslator CreateInstance()
{
return new EnglishToItalianTranslator();
}
in fine andiamo a modificare il file di configurazione (.config) aggiungendo l'attributo factory-method ed indicando il nome del metodo da utilizzare:<object id="MyBasicTranslator"
type="SpringSeries.Core.FactoryMethod.EnglishToItalianTranslator, 02.FactoryMethod"
...
Dopo tante chiacchere cominciamo ad entrare nel vivo e vediamo come configurare e creare un semplice oggetto tramite il suo costruttore di default. Prendiamo come esempio una classe, volutamente semplificata, che deve tradurre una frase dall'inglese all'italiano, essa verrà modificata ed evoluta nei futuri post. La classe risulterà simile alla seguente:public class EnglishToItalianTranslator
{
public EnglishToItalianTranslator()
{
}
public string Translate(string phraseToTranslate)
{
string phraseTranslated;
//qui va l'algoritmo di traduzione...
...
Le possibili integrazioni sono due: Viene fornito un file XSD che ci aiuta nella scrittura (tramite IntelliSense) e nella validazione del file di configurazione di Spring.NET. Il file è raggiungibile a questo url: http://www.springframework.net/xsd/spring-objects.xsd e va salvato in una delle seguenti path di Visual Studio, a seconda della versione posseduta: VS2003: C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Packages\schemas\xml\ VS2005: C:\Program Files\Microsoft Visual Studio 8\Xml\Schemas Se utilizzate il Setup verra registrata la documentazione delle API di Spring.NET. Technorati Tags: Spring.NET
Il framework Spring.NET è ideato per non essere intrusivo, proprio per questo motivo è composto da una serie di macro funzionalità suddivise in moduli, utilizzabili anche singolarmente a seconda delle nostre esigenze. Essi sono: Spring.Core: Rappresenta il punto contrale del framework, questo blocco è composto da un Inversion of Control Container e da una serie di "utility" per vare arie funzionali come Collection, Threading e Pooling. Spring.AOP: In questo modulo sono implementate le funzionalita di Aspect Oriented Programming. Spring.Web: qui troviamo una serie di estenzioni per migliorare lo sviluppo di applicazioni ASP.NET. Spring.Services: questa area integra le tecnologie a servizi come Windows Services,...
Con questo post inauguro una nuova serie dedicata a questo application framework open source che ci aiuta nello sviluppo di applicazioni di tipo enterprise. Spring.NET, sviluppato da Mark Pollack e dal suo team, attualmente in versione 1.1 RC1 (Release Candidate 1), è il porting idiomatico del più noto e famoso framework Spring per Java. Per iniziare ecco una serie di link: Home Spring.NET Source Forge Project Download Documentation Issue Tracker Forum Podcast - .NET Rocks! Per tutti quelli interessati ho creato una nuova categoria ad-hoc: Spring.NET (rss) Technorati Tags: Spring.NET