2014-10-10 13 views
5

Mam aplikację ASP.NET MVC, dla której chcę rejestrować zdarzenia. Mam już klasę Log z wszystkimi niezbędnymi narzędziami, ale muszę ją utworzyć i jawnie zamknąć (ponieważ otwiera pliki, więc nie mogę polegać na GC). Moje działania będzie wyglądać następująco:Wykonaj kod przed/po każdym działaniu kontrolera

public ActionResult MainMenu() 
{ 
    CreateLog(); 

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

    CloseLog(); 
    return View(mModel); 
} 

Albo mógłbym użyć using blok, ale byłoby trochę mniej inwazyjne i byłoby stworzyć problemy z obsługi wyjątków. Przeczytałem o ActionFilters, którego mogłem użyć do utworzenia i zamknięcia mojego logu, ale wtedy nie miałbym możliwości dostępu do obiektu Log wewnątrz metody.

Masz jakieś sugestie? Jak mogę uniknąć powtarzania kodu?

+0

Możliwy duplikat [Uruchom metodę w każdym żądaniu w MVC, C#?] (Https://stackoverflow.com/questions/9511462/run-a-method-in-each-request-in-mvc -c) – Liam

Odpowiedz

13

Jeśli inne sugestie nie działa lub jeśli chcesz robić rzeczy innych niż tylko zalogowaniu również zdawać sobie sprawę, że można zastąpić metodę OnActionExecuting (często w klasie bazowej do ponownego użycia).

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

Dzięki! Właśnie tego szukałem! – Simone

2

Polecam, abyś popchnął obiekt Logger (prawdopodobnie ILogger) jako zależność od kontrolera. Możesz kontrolować czas życia tego obiektu rejestratora przez kontener DI (np. Unity) - i jeśli to konieczne, możesz określić jego czas życia jako zakres żądania. Inną zaletą tego urządzenia jest to, że twój kod pozostanie testowalny.

+0

Całkiem dobrze, ale w jaki sposób chciałbym się zalogować metod, które nie są członkami kontrolera? – Simone

+0

Możesz po prostu przekazać swój obiekt rejestratora do dowolnych innych metod, aby mogli z niego korzystać. Ewentualnie, jeśli lepiej pasuje do twoich potrzeb, możesz zaimplementować swój rejestrator (lub po prostu zawinąć już istniejącą implementację rejestratora) jako [Kontekst środowiskowy] (http://blogs.msdn.com/b/ploeh/archive/2007/07/23 /ambientcontext.aspx). – aberkes

+0

Podoba mi się rozwiązanie kontekstu otoczenia (podczas gdy wolałabym nie przekazywać logu, ponieważ wolałbym, aby moja metoda nie wiedziała tak wiele o zagadnieniu przekrojowym). Jednak co z bezpieczeństwem wątków? Muszę zamknąć otwarte pliki dziennika, więc za każdym razem (na końcu żądania) muszę zamknąć dziennik. Nie mogę mieć singletonu (lub quasi-singleton), w przeciwnym razie istniałby on na żądanie. Wiele dzienników spróbuje otworzyć ten sam plik, awaria (i utrata zdarzeń); pojedynczy dziennik może zamknąć plik, podczas gdy inna żądana czynność nadal zawiera elementy do zalogowania. – Simone

Powiązane problemy