2012-11-03 13 views
13

Ho vari metodi individuali che devono tutti eseguire le stesse funzioni prima di continuare con la loro implementazione. Ora potrei implementare queste funzioni in ogni metodo, ma mi stavo chiedendo se c'è un modo per sfruttare lo attributes per fare questo? Come un esempio molto semplice, tutte le chiamate di rete devono verificare la presenza di una connessione di rete.Utilizzo degli attributi per chiamare i metodi

public void GetPage(string url) 
{ 
    if(IsNetworkConnected()) 
     ... 
    else 
     ...   
} 

Questo potrebbe funzionare, ma avrei dovuto chiamare il metodo IsNetworkConnected per ogni metodo che utilizza la rete e gestire individualmente. Invece, mi piacerebbe fare questo

[NetworkCall] 
public void GetPage(string url) 
{ 
    ... 
} 

Se la rete non è disponibile, un metodo di errore si chiama invece e GetPage viene ignorato, altrimenti GetPage viene richiamato.

Sembra molto simile alla programmazione orientata agli aspetti, ma non voglio implementare un intero framework per alcune chiamate. Questo è più un esercizio di apprendimento che uno di implementazione, quindi ero curioso di sapere come qualcosa del genere sarebbe meglio implementato.

+0

E l'ereditarietà?Fai in modo che tutti derivino da una classe "Network" di base o qualcosa del genere. – gdoron

risposta

3

Si può usare PostSharp, è framework aspect-oriented per .NET, sembra quite easy to use:

static void Main(string[] args) 
{ 
    Foo(); 
} 

[IgnoreMethod(IsIgnored=true)] 
public static void Foo() 
{ 
    Console.WriteLine("Executing Foo()..."); 
} 

[Serializable] 
public class IgnoreMethodAttribute : PostSharp.Aspects.MethodInterceptionAspect 
{ 
    public bool IsIgnored { get; set; } 

    public override void OnInvoke(PostSharp.Aspects.MethodInterceptionArgs args) 
    { 
     if (IsIgnored) 
     { 
      return; 
     } 

     base.OnInvoke(args); 
    } 
} 

aspetti del metodo a livello di funzione è disponibile nella versione gratuita : http://www.sharpcrafters.com/purchase/compare

Prestazioni in fase di esecuzione:

Perché PostSh arp è una tecnologia di compilazione, la maggior parte del costoso lavoro viene svolto in fase di compilazione, in modo che le applicazioni si avviino rapidamente ed eseguano rapidamente. Quando genera codice, PostSharp presuppone che chiamare un metodo virtuale o ottenere un campo statico sia un'operazione costosa. Contrariamente a quanto si dice, PostSharp non usa System.Reflection in fase di esecuzione. http://www.sharpcrafters.com/postsharp/performance

+0

Ho pensato che PostSharp sarebbe stato inefficiente perché doveva attraversare uno strato di riflessione ... ma * sembra * come se facesse la maggior parte delle cose in fase di compilazione. API piacevole e pulita. Potrei provare per alcuni dei miei progetti. – mpen

+0

Sì, ho appena letto sul loro sito web: '" Contrariamente a quanto si dice, PostSharp non usa System.Reflection in fase di esecuzione. "' http://www.sharpcrafters.com/postsharp/performance Quindi, la performance non lo fa t sembra essere un problema – maximpa

+0

Grazie, esaminerò PostSharp. Non volevo particolarmente usare un framework, ma non sembra ci sia un'alternativa. – keyboardP

1

Non penso che sia possibile farlo solo con attributes, perché non vengono eseguiti dal runtime se non si sta facendo qualcosa attivamente con loro. Un approccio leggero sarebbe Ninject with Interceptions extension, è un framework, ma molto sottile, e uno potrebbe già essere utilizzato per DI comunque.

Un'altra opzione, ma un po 'più complessa, potrebbe essere basata su MEF e quindi è possibile utilizzare gli attributi e fare qualcosa durante con loro durante l'attivazione.

1

Hai ragione, suona molto come AOP.
Quello che stai dopo sembra un intreccio di tempo compilato? Cioè l'attributo è trasformato in codice aggiuntivo dal compilatore.
Si potrebbe studiare il modo per implementare questo ...
Generating additional code through a custom attribute
http://www.cs.columbia.edu/~eaddy/wicca/ &
http://www.sharpcrafters.com/aop.net/compiletime-weaving
si riferiscono tutti a strumenti e tecniche per fare questo.

Oppure è possibile utilizzare un framework AOP. IMHO, dovresti guardare i framework AOP.