Asp.Net MVC 控制器:带有 Spring.Net 的声明式 AOP [英] Asp.Net MVC Controller: declarative AOP with Spring.Net

查看:25
本文介绍了Asp.Net MVC 控制器:带有 Spring.Net 的声明式 AOP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有可能,Spring.Net Aspects 不适用于 Asp.Net Controller?

Is it possible, that Spring.Net Aspects don't work with Asp.Net Controller?

我想在控制器的 Action 方法上配置事务,但代理似乎没有触发.

I want to configure transactions on Action methods of Controllers but the proxy doesn't seem to trigger.

<object id="ControllerClassPointcut" type="Spring.Aop.Support.SdkRegularExpressionMethodPointcut, Spring.Aop">
  <property name="patterns">
    <list>
      <value>xxx.Controllers.CompanyController.*</value>
    </list>
  </property>
</object>

<aop:config>
  <aop:advisor pointcut-ref="ControllerClassPointcut" advice-ref="TxAdvice"/>
  <!-- TxAdvice taken from ServiceContext -->
</aop:config>

<tx:advice id="TxAdvice" transaction-manager="TransactionManager">
  <tx:attributes>
    <tx:method name="*" propagation="Required"/>
  </tx:attributes>
</tx:advice>

而 CompanyController 的 action 方法是:

and the action method of the CompanyController is:

    [HttpPost]
    public virtual ActionResult Create(Guid id, CompanyonViewModel vm)
    {
       ...
    }

但是我的建议没有生效,尽管切入点被识别.如果我将控制器以外的其他类作为切入点,它会起作用.

but I the advice does not take effect although the pointcut is recognized. If I take an other class than a controller as pointcut it works.

对于某些方法,建议有效.例如,对于存储库的 setter.但是 Sprint.Net 不承认调用了 action 方法Create"

for some methods the advice works. For example for the setter for the repository. But Sprint.Net does not recognize that the action method "Create" is called

候选人是:'xxx.Controllers.CompanyController.set_CompanyService';模式是 'xxx.Controllers.CompanyController.*';匹配=真候选顾问 [DefaultObjectFactoryPointcutAdvisor: 切入点 [Spring.Aop.Support.SdkRegularExpressionMethodPointcut];建议对象 = 'TxAdvice'] 接受目标类型 [xxx.Controllers.CompanyController]

Candidate is: 'xxx.Controllers.CompanyController.set_CompanyService'; pattern is 'xxx.Controllers.CompanyController.*'; matched=True Candidate advisor [DefaultObjectFactoryPointcutAdvisor: pointcut [Spring.Aop.Support.SdkRegularExpressionMethodPointcut]; advice object = 'TxAdvice'] accepted for targetType [xxx.Controllers.CompanyController]

感谢您的帮助

推荐答案

我在 [Transaction] 属性(使用 Spring.AOP).在我的例子中,我从同一个类中调用了 [Transaction] 标记的方法,并惊讶于事务建议没有触发.

I had a similar a problem with the [Transaction] attribute (which works using Spring.AOP). In my case, I called the [Transaction] flagged methods from within the same class and was surprised that the transaction advice didn't fire.

解释是,当从类中调用一个 [Transaction] 标记的方法时,你持有对真实实例的引用,而不是 AOP 代理的实例,因此调用不会得到拦截了.

The explanation was, that when calling a [Transaction] marked method from within the class, you hold a reference to the real instance instead of the AOP-proxied instance, therefore the call does not get intercepted.

当向 MVC 应用程序发出请求时,将从请求 url 中选择一个控制器(来自 IControllerFactory 实例).在这个控制器上,Execute 方法被调用,它反过来负责调用动作.所以我认为 action 方法总是从控制器内部调用.这意味着根据定义,操作方法永远不会被拦截.这将解释为什么这些切入点被识别,但不触发.

When a request is made to an MVC app, then from the request url a controller is chosen (from the IControllerFactory instance). On this controller, the Execute method is called, which in turn is responsible for calling the actions. So I think that action methods are always called from within the controller. Which means that by definition action methods will never get intercepted. This would explain why those pointcuts are recognized, but don't fire.

如果我上其他课程而不是控制器作为切入点工作

if I take an other class than a controller as pointcut it works

它还解释了为什么在控制器之外的其他类上的切入点会触发:它们很可能是从控制器调用的,控制器将持有对其他类的实例的 AOP 代理引用.

It also explains why pointcuts on other classes than controllers do fire: they are likely called from a controller, which will hold a AOP-proxied reference to instances of the other classes.

... 对于某些方法,建议有效...例如对于存储库

... for some methods the advice works ... For example for the setter for the repository

我假设您的(例如)CompanyController.CustomerController 具有使用 DI 设置的属性 CustomerRepository.这个切入点触发是有道理的,因为 setter 是从 CompanyController.CustomerController 外部调用的,例如由您的 DI 容器(或您的 ControllerFactory)调用.

I assume that your (for instance) CompanyController.CustomerController has a property CustomerRepository, set using DI. It makes sense that this pointcut fires, because the setter is called from outside the CompanyController.CustomerController, for instance by your DI container (or your ControllerFactory).

一个解决方案可能是引入服务对象,您可以在其上定义您现在在控制器上拥有的事务建议.从您的控制器中,您调用这些服务对象的方法 - 然后切入点将被触发.

A solution could be to introduce service objects, on which you define the transaction advice that you now have on your controllers. From your controllers, you call methods on these service objects - and then the pointcuts will fire.

这篇关于Asp.Net MVC 控制器:带有 Spring.Net 的声明式 AOP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆