【问题标题】:ASP.NET MVC 3, Action Filters, and Autofac Dependency InjectionASP.NET MVC 3、动作过滤器和 Autofac 依赖注入
【发布时间】:2011-01-14 21:01:00
【问题描述】:

ASP.NET MVC 2 我有一个名为 [Transaction]ActionFilterAttribute 在执行操作之前启动 NHibernate 事务并在之后提交或回滚它,具体取决于是否出现异常被抛出。 ISession 实例是HttpRequestScoped() 并由Autofac 注入。它看起来像这样并且效果很好:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public sealed class TransactionAttribute : ActionFilterAttribute
{
    private ITransaction transaction;

    public TransactionAttribute()
    {
        this.Order = 0;
    }

    public ISession Session
    {
        get;
        set;
    }

    public override void OnActionExecuted(
        ActionExecutedContext filterContext)
    {
        if (this.Session != null && this.transaction != null)
        {
            try
            {
                if (this.transaction.IsActive)
                {
                    if (filterContext.Exception == null)
                    {
                        this.transaction.Commit();
                    }
                    else
                    {
                        this.transaction.Rollback();
                    }
                }
            }
            finally
            {
                this.transaction.Dispose();
                this.transaction = null;
            }
        }
    }

    public override void OnActionExecuting(
        ActionExecutingContext filterContext)
    {
        if (this.Session != null)
        {
            this.transaction = this.Session.BeginTransaction();
        }
    }
}

太棒了。 Seems to be a common pattern.

ASP.NET MVC 3 注释中,我在“重大更改”(强调我的)下看到了这个小简介:

在以前版本的 ASP.NET MVC 中,操作过滤器是根据请求创建的,除了少数情况。这种行为从来都不是一种有保证的行为,而只是一个实现细节,过滤器的约定是认为它们是无状态的。在 ASP.NET MVC 3 中,过滤器被更积极地缓存。因此,任何不正确地存储实例状态的自定义操作过滤器都可能被破坏。

哎呀。

  • 这是否意味着如果我升级到 MVC 3,我会被淹没?
  • 如果不再为每个请求实例化操作过滤器,我们如何将请求范围的依赖项添加到我们的操作过滤器中?

感谢您的任何见解。

【问题讨论】:

    标签: asp.net-mvc-3 autofac action-filter


    【解决方案1】:

    我刚刚在谷歌论坛上问了一个类似的问题。 这是链接https://groups.google.com/forum/#!topic/autofac/a0qqp2b3WA8

    我得到了答案:

    builder.RegisterType<ExtensibleActionInvoker>().As<IActionInvoker>();
    
    
    builder.RegisterControllers(Assembly.GetExecutingAssembly()).InjectActionInvoker();
    

    然后你可以在你的属性中使用属性注入。

    【讨论】:

    • 是的,发行说明注释似乎适用于 MVC 中的默认设置——但 IoC 容器会覆盖它以提供自己的行为。
    【解决方案2】:

    哎呀.... Nicholas,您可能需要将您的 ISession 和 Transaction 存储在 HttpContext.Items 中,您应该能够通过 ActionExecutedContext/ActionExecutingContext(也许将其设置在 OnActionExecuting 事件处理程序中)来获取它们,而不是将它们保留在实例成员中。要么这样,要么你可以在你的过滤器中调用一个 ServiceLocator 来为你抓取它们(也很糟糕)。

    现在我必须查看我的 MVC 3 代码,看看我自己是否有任何类似的问题!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多