Invest in people before investing in tools

Il blog di Matteo Baglini
posts - 118, comments - 95, trackbacks - 697

[Spring.NET #33] Spring.Aop, Advice

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 l'interfaccia IAfterReturningAdvice e permette di introdurre codice soltanto dopo l'invocazione del metodo target.
  • ThrowAdvice: implementa l'interfaccia IThrowAdvice e permette di introdurre codice all'intercettazione di una eccezione.

L'ordine di esecuzione degli Advice dello stesso tipo può essere controllata se quest'ultimi implementano l'interfaccia IOrdered.

Gli Advice sono classificabili in due categorie: per classe e per istanza, differenti dal fatto che la seconda categoria dipende dallo stato interno della classe target mentre la prima no. Gli Advice elencati precedentemente fanno tutti parte della prima categoria. L'interfaccia IAdvice, invece, fa parte della seconda categoria e permette di creare dei mixin introducendo metodi e proprietà all'oggetto target.

Procediamo con l'esempio incominciato nel precedente post. In questo episodio estrapoliamo il codice per la validazione dell'utente dalla classe TransferService e lo inseriamo una classe Advice, creando la classe GenericPrincipalAroundAdvice. Il risultato sarà il seguente:

   1: public class TransferService : ITransferService
   2: {
   3:     public void Transfer(Account fromAccount, Account toAccount, int amount)
   4:     {
   5:         fromAccount.withdraw(amount);
   6:         toAccount.deposit(amount);
   7:     }
   8: }
   1: public class GenericPrincipalAroundAdvice : IMethodInterceptor
   2: {
   3:     private string _role = String.Empty;
   4:     public string Role
   5:     {
   6:         get { return _role; }
   7:         set { _role = value; }
   8:     }
   9:  
  10:     public object Invoke(IMethodInvocation invocation)
  11:     {
  12:         IPrincipal _currentPrincipal = Thread.CurrentPrincipal;
  13:         if (!_currentPrincipal.IsInRole(_role))
  14:             throw new SecurityException("The logged user can't perform Transfer Account operation.");
  15:  
  16:         object returnValue = invocation.Proceed();
  17:  
  18:         return returnValue;
  19:     }
  20: }

Notiamo alla riga 16 l'infocazione del metodo intercettato (Tansfer) tramite il metodo Proceed(). In fine aggiorniamo la configurazione dell'Advisor impostando la proprietà Advice:

<object id="aroundAdvisor" type="Spring.Aop.Support.NameMatchMethodPointcutAdvisor, Spring.Aop">
  <property name="Advice">
    <object type="SpringSeries.Aop.Advice.GenericPrincipalAroundAdvice, 02.Advice">
      <property name="Role" value="BankUser" />
    </object>
  </property>
  <property name="MappedName" value="Transfer" />
</object>

Print | posted on sabato 10 maggio 2008 13:42 | Filed Under [ .NET OpenSource Spring.NET ]

Powered by:
Powered By Subtext Powered By ASP.NET