2011-09-01 63 views
4

我遵循有关如何在ASP.NET MVC使用温莎和log4net的是AOPASP.NET MVC + WIndsor + Log4Net如何截取模型?

http://cangencer.wordpress.com/2011/06/02/asp-net-mvc-3-aspect-oriented-programming-with-castle-interceptors/

的优秀教程文章告诉我如何写日志的每个控制器的行动时不接触任何控制器 文章还声明我可以用模型中的方法来做到这一点,但没有说明如何。

能否请你帮我

+0

为什么要截取MVC模型?恕我直言,这是一个代码味道... –

回答

1

你可以写你的模型完全一样log4net的拦截器做同样的方式拦截。 只能用作模型合约的ctor参数。

public ControllerModelInterceptor(IModel model) 
{ 
    this.model = model; 
} 
+0

谢谢,你的答案听起来不错,但我太新来这个框架来完全理解它。 – hormkralob

2

我是问题中的链接的作者,所以首先感谢您的客气话。现在到了你的问题:

这是一个很大的困难和/或不切实际的在你的模型使用拦截器,因为拦截工作,你应该只通过城堡容器访问你的模型的实例。看到问题了吗?

假设你有一个名为Book模型对象,你想拦截上的所有通话,你需要确保你从未使用类似通过城堡Booknew Book(),只访问实例。拦截器通过代理工作,并且在您自己创建对象的实例时不起作用。这意味着能够有效地使用拦截器,您需要围绕此构建整个应用程序,这可能不是最好的主意。即每次你想要一个Book的实例时,你需要问Castle而不是Container.Resolve<Book>()。我个人并不觉得这个方法很优雅。我认为它打破了封装和良好面向对象设计的原则。

拦截器很容易处理控制器,因为所有的控制器都只在一次地方初始化,我们挂钩的地方是ControllerFactory。然而,模型对象可以用不同的方式进行初始化,因为它们确实应该描述您的域模型。

但是可能有几种方法可以解决这个问题。第一个我能想到的是使用一个ORM,比如NHibernate,它已经在后台使用了拦截器,你可以为各种事件(比如保存,更新或者任何方法调用)调用拦截器。限制将是拦截器只能在从数据库中检索的模型上工作。

另一种选择是使用编译时重写器,如Postsharp,它将为您提供在编译后重写代码的方法。通过这种方式,可以使用特定属性添加和删除您标记的每个方法的开始和结尾的其他调用。

+0

其实它不是我想拦截的模型,我想记录SQL语句执行。我从来没有使用NHibernate,并从您的答案,我认为是时候我尝试它。但我仍然不确定是否可以将NHibernate挂钩到Windsor来编写日志。我可能会再次问。非常感谢哟。 – hormkralob

+0

@hormkralob,在这种情况下,nhib应该很适合你,因为你可以很容易地记录每个执行的sql语句。将NHibernate挂入Castle也很容易。 –