Asp.Net MVC Controller: декларативный AOP с Spring.Net

Возможно ли, что Spring.Net Аспекты не работают с Asp.Net Controller?

Я хочу настроить транзакции в методах действия контроллеров, но прокси не запускается.

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

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

но я совет не вступает в силу, хотя pointcut признается. Если я возьму другой класс, а не контроллер в качестве pointcut, он работает.

для некоторых методов совет работает. Например, для установщика для хранилища. Но Sprint.Net не признает, что вызывается метод действия "Создать"

Кандидат: "xxx.Controllers.CompanyController.set_CompanyService"; шаблон это 'xxx.Controllers.CompanyController.*'; matched=True Candidate advisor [DefaultObjectFactoryPointcutAdvisor: pointcut [Spring.Aop.Support.SdkRegularExpressionMethodPointcut]; Аргумент object = 'TxAdvice'] принят для targetType [xxx.Controllers.CompanyController]

Спасибо за вашу помощь

2 ответа

Решение

У меня была похожая проблема с [Transaction] атрибут (который работает с использованием Spring.AOP). В моем случае я назвал [Transaction] помечал методы внутри одного класса и был удивлен, что совет по транзакции не сработал.

Объяснение было то, что при вызове [Transaction] помечая метод внутри класса, вы держите ссылку на реальный экземпляр вместо экземпляра с проксированием AOP, поэтому вызов не перехватывается.

Когда выполняется запрос к приложению MVC, из URL-адреса запроса выбирается контроллер (из IControllerFactory пример). На этом контроллере Execute вызывается метод, который в свою очередь отвечает за вызов действий. Поэтому я думаю, что методы действия всегда вызываются из контроллера. Это означает, что по определению методы действия никогда не будут перехвачены. Это объяснило бы, почему эти точки обнаружены, но не срабатывают.

если я возьму другой класс, чем контроллер, как pointcut, он работает

Это также объясняет, почему запускаются pointcut для других классов, кроме контроллеров: они, скорее всего, вызываются из контроллера, который будет содержать ссылку на прокси AOP на экземпляры других классов.

... для некоторых методов совет работает... Например для установщика для хранилища

Я предполагаю, что ваш (например) CompanyController.CustomerController имеет свойство CustomerRepository, установите с помощью DI. Имеет смысл, что этот pointcut срабатывает, потому что сеттер вызывается извне CompanyController.CustomerControllerнапример, вашим DI-контейнером (или вашим ControllerFactory).

Решением может быть введение сервисных объектов, для которых вы определяете рекомендации по транзакциям, которые вы теперь имеете на своих контроллерах. С ваших контроллеров вы вызываете методы для этих сервисных объектов - и затем запускаются pointcuts.

Можете ли вы попробовать с конфигурацией

<aop:config proxy-target-type="true">

Это создаст прокси на основе наследования. Вам может понадобиться загрузить последнюю ночную сборку spirng.net, чтобы это работало (не 1.3.0).

Другие вопросы по тегам