2014-04-23 46 views
7

我目前正在ASP.NET中開發MVC應用程序,我試圖分離關注點,以便最終得到更清晰和更可維護的代碼。ASP.NET MVC中的面向方面的編程

因此,作爲一個起點,我正在考慮採伐方面。 我的想法是記錄(最初)每個控制器中每個方法的調用和返回。 我將這個邏輯放在一個單獨的類上,專門用於日誌記錄,所以我不會在任何地方使用日誌語句來混淆我的代碼。

我還需要訪問Http請求,以便我可以獲取客戶端信息。

有沒有一個完整的方法來做到這一點? ASP.NET MVC可以像Java中的AspectJ一樣用於方面文件嗎?

另外,以後可以配置它來記錄滿足某些條件的方法嗎? (如簽名,返回值,異常投擲等)

非常感謝!

回答

10

您可以使用屬性以面向方面的方式實現功能。要與你的功能,圍繞操作方法,然後只需要按照你的屬性來裝飾:

[CustomLogger] 
public ActionResult Index() 
{ 
    // Doing something here ... 
    return View(); 
} 

您可以裝飾一個單一的操作方法與屬性,可將整個控制器,甚至可以通過全局應用屬性ASP.NET MVC的GlobalFilterCollection

這裏是你如何申報您的屬性:

public class CustomLoggerAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     base.OnActionExecuted(filterContext); 

     // Here goes your logic 
    } 

    // ... 
} 

ActionFilterAttribute類可以覆蓋兩個方法,所以你可以掛接到ASP.NET MVC的行動執行流水線:

  • OnActionExecuting
  • OnActionExecuted
  • OnResultExecuting
  • OnResultExecuted

可以通過傳遞給上述方法中的參數(如ActionExecutedContext)訪問請求的變量。

+0

這很有趣,它可以在控制器級別使用嗎?我的意思是,註釋該類,以便它自動適用於該控制器的所有操作。 儘管如此,我並不喜歡這樣的想法:註釋我的控制器,我想的是更透明的方式,因此控制器和日誌方面是完全獨立的。控制器不應該知道它是否被記錄。 –

+2

@MatiCicero現在你比我快了。 ;-)是的,你可以在ASP.NET MVC應用程序中將該屬性的範圍限定爲單個動作方法,整個控制器或每個控制器。這樣,沒有一個控制器需要知道屬性 - 僅使用'GlobalFilterCollection.Filters';此外,您不能忘記將屬性應用於某個控制器,這對於身份驗證/授權非常有用。 –

+0

好吧,現在我們正在說@Marius Schulz! 我喜歡這個想法,它可以用來不記錄所有的行動,但只是某些滿足某些簽名? 我正在考慮使用反射也許,但如果有一個這樣做的自動化的方式我都耳朵! –