Asp.Net MVC Controller: декларативный AOP с Spring.Net - PullRequest
3 голосов
/ 25 ноября 2010

Возможно ли, что 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. *'; соответствует = True Советник кандидата [DefaultObjectFactoryPointcutAdvisor: pointcut [Spring.Aop.Support.SdkRegularExpressionMethodPointcut]; Аргумент object = 'TxAdvice'] принят для targetType [xxx.Controllers.CompanyController]

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

Ответы [ 2 ]

4 голосов
/ 03 декабря 2010

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

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

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

2 голосов
/ 03 декабря 2010

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

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

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

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

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

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

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

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

...