2014-10-10 14 views
5

Ich habe eine ASP.NET MVC-Anwendung, für die ich Ereignisse protokollieren möchte. Ich habe bereits eine Log-Klasse mit allen Werkzeugen, die ich brauche, aber ich muss es instanziieren und explizit schließen (weil es Dateien öffnet, so kann ich mich nicht auf den GC verlassen). Meine Handlungen würden wie folgt aussehen:Code vor/nach jeder Controller-Aktion ausführen

public ActionResult MainMenu() 
{ 
    CreateLog(); 

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

    CloseLog(); 
    return View(mModel); 
} 

Oder ich einen using Block verwenden könnte, aber es wäre nur ein wenig weniger aufdringlich und es würde Schwierigkeiten mit Ausnahmebehandlung erstellen. Ich habe über ActionFilters gelesen, die ich verwenden könnte, um mein Protokoll zu erstellen und zu schließen, aber dann hätte ich keine Möglichkeit, auf das Protokollobjekt innerhalb der Methode zuzugreifen.

Haben Sie Vorschläge? Wie kann ich vermeiden, den Code wiederholen zu müssen?

+0

Mögliche Duplikat [Führen Sie eine Methode in jeder Anforderung in MVC, C#?] (Https://stackoverflow.com/questions/9511462/run-a-method-in-each-request-in-mvc -c) – Liam

Antwort

13

Wenn die anderen Vorschläge nicht funktionieren oder wenn Sie andere Dinge tun müssen, als nur sich auch bewusst sein, dass Sie die Anmeldung OnActionExecuting Methode überschreiben können (oft in einer Basisklasse für die Wiederverwendung).

// 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

Danke! Genau das habe ich gesucht! – Simone

2

Ich würde Ihnen empfehlen, ein Logger (wahrscheinlich ILogger) Objekt als eine Abhängigkeit zu Ihrem Controller zu schieben. Sie können die Lebensdauer dieses Loggerobjekts über einen DI-Container (z. B. Unity) steuern. Falls erforderlich, können Sie die Lebensdauer des Objekts als Anforderungsbereichs definieren. Der andere Vorteil dieser Version ist, dass Ihr Code testbar bleibt.

+0

Ziemlich gut, aber wie würde ich mich über Methoden anmelden, die nicht Mitglieder des Controllers sind? – Simone

+0

Sie können Ihr Logger-Objekt einfach an andere Methoden übergeben, damit sie es auch verwenden können. Alternativ können Sie Ihren Logger (oder einfach nur Ihre bereits vorhandene Logger-Implementierung) als [Umgebungskontext] (http://blogs.msdn.com/b/ploeh/archive/2007/07/23) implementieren, wenn er Ihren Anforderungen besser entspricht /ambientcontext.aspx). – aberkes

+0

Ich mag die Umgebungskontextlösung (obwohl ich das Protokoll lieber nicht weitergeben würde, da ich meine Methode bevorzugen würde, nicht so viel über eine Querschnittsaufgabe zu wissen). Was ist jedoch mit Thread-Sicherheit? Ich muss offene Protokolldateien schließen, sodass ich jedes Mal (am Ende der Anfrage) das Protokoll schließen muss. Ich kann kein Singleton (oder Quasi-Singleton) haben, sonst würde es über Anfragen existieren. Mehrere Protokolle würden versuchen, die gleiche Datei zu öffnen, fehlgeschlagen (und Ereignisse zu verlieren); Ein einzelnes Protokoll kann die Datei schließen, während eine andere angeforderte Aktion noch zu protokollierende Daten enthält. – Simone

Verwandte Themen