2014-10-10 16 views
5

Ho un'applicazione ASP.NET MVC per cui voglio registrare eventi. Ho già una classe Log con tutti gli strumenti di cui ho bisogno, ma devo creare un'istanza e chiuderla in modo esplicito (perché apre i file, quindi non posso dipendere dal GC). Le mie azioni sarebbero simile a questa:Esegui codice prima/dopo ogni azione del controller

public ActionResult MainMenu() 
{ 
    CreateLog(); 

    // Do controller stuff 
    Log(message); 
    // Do more controller stuff 

    CloseLog(); 
    return View(mModel); 
} 

Oppure avrei potuto utilizzare un blocco using, ma sarebbe solo un po 'meno intrusivo e sarebbe creare problemi con la gestione delle eccezioni. Ho letto su ActionFilters, che potrei usare per creare e chiudere il mio log, ma non avrei modo di accedere all'oggetto Log all'interno del metodo.

Avete qualche suggerimento? Come potrei evitare di dover ripetere il codice?

+0

Eventuali duplicati di [Eseguire un metodo in ogni richiesta in MVC, C#?] (Https://stackoverflow.com/questions/9511462/run-a-method-in-each-request-in-mvc -c) – Liam

risposta

13

Se gli altri suggerimenti non funzionano o se si devono fare cose diverse da solo accedendo anche essere consapevoli che si può sovrascrivere il metodo OnActionExecuting (spesso in una classe base per il riutilizzo).

// Custom controller. 
public class CustomController : Controller 
{ 
    protected override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     // Do whatever here... 
    } 
} 

// Home controller. 
public class HomeController : CustomController 
{ 
    // Action methods here... 
} 
+0

Grazie! Questo e 'esattamente quello che stavo cercando! – Simone

2

Si consiglia di inserire un oggetto Logger (probabilmente ILogger) come dipendenza dal controller. È possibile controllare la durata di questo oggetto logger da un contenitore DI (ad esempio Unity) e, se necessario, è possibile definirne la durata come ambito della richiesta. L'altro vantaggio di questa soluzione è che il tuo codice rimarrà testabile.

+0

Abbastanza buono, ma come farei per accedere ai metodi che non sono membri del controller? – Simone

+0

È possibile passare semplicemente l'oggetto del registratore ad altri metodi in modo che possano anche usarlo. In alternativa, se si adatta meglio alle tue esigenze, puoi implementare il tuo logger (o semplicemente avvolgere l'implementazione del tuo logger già esistente) come [Ambient Context] (http://blogs.msdn.com/b/ploeh/archive/2007/07/23 /ambientcontext.aspx). – aberkes

+0

Mi piace la soluzione Ambient Context (mentre preferirei non passare il Log in quanto preferirei che il mio metodo non sapesse molto su una preoccupazione trasversale). Tuttavia, per quanto riguarda la sicurezza dei thread? Ho bisogno di chiudere i file di log aperti, quindi ogni volta (alla fine della richiesta), devo chiudere il registro. Non posso avere un singleton (o quasi-singleton), altrimenti esisterebbe tra le richieste. Log multipli proverebbero ad aprire lo stesso file, in mancanza (e perdendo eventi); un singolo registro può chiudere il file mentre un'altra azione richiesta ha ancora elementi da registrare. – Simone

0

È possibile utilizzare i moduli perché entrambi siedono in una pipeline e possono fornire l'elaborazione pre e post per l'esecuzione di base di una richiesta. BeginRequest/ActionExecuting e EndRequest/ResultExecuted. Entrambi forniscono anche ganci di autorizzazione.

http://msdn.microsoft.com/en-us/library/aa719858(v=vs.71).aspx

Problemi correlati