ASP.NET MVC 3, Action Filters, and Autofac Dependency Injection

╄→尐↘猪︶ㄣ 提交于 2019-11-29 20:15:57

问题


On ASP.NET MVC 2 I have an ActionFilterAttribute called [Transaction] that starts an NHibernate transaction before executing the action and commits or rolls it back afterward, depending on whether or not an exception was thrown. The ISession instance is HttpRequestScoped() and injected by Autofac. It looks like this and works great:

[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();
        }
    }
}

Fantastic. Seems to be a common pattern.

In the ASP.NET MVC 3 notes, I see this little blurb under "Breaking Changes" (emphasis mine):

In previous versions of ASP.NET MVC, action filters were created per request except in a few cases. This behavior was never a guaranteed behavior but merely an implementation detail and the contract for filters was to consider them stateless. In ASP.NET MVC 3, filters are cached more aggressively. Therefore, any custom action filters which improperly store instance state might be broken.

Oops.

  • Does this mean I'm hosed if I upgrade to MVC 3?
  • If action filters are no longer instanced per request, how will we get request-scoped dependencies into our action filters?

Thanks for any insight.


回答1:


I just asked a similar question on google forums. Here is the link https://groups.google.com/forum/#!topic/autofac/a0qqp2b3WA8

I got the answer:

builder.RegisterType<ExtensibleActionInvoker>().As<IActionInvoker>();


builder.RegisterControllers(Assembly.GetExecutingAssembly()).InjectActionInvoker();

Then you can use property injection in your attributes.




回答2:


Oh yuck.... Nicholas, you might need to store your ISession and Transaction in HttpContext.Items, which you should be able to get to via the ActionExecutedContext/ActionExecutingContext (perhaps setting it in the OnActionExecuting event handler), instead of keeping them in instance members. Either that, or you could call a ServiceLocator inside your filter to grab them for you (also yuck).

Now I have to go look through my MVC 3 code and see if I have any similar problems myself!



来源:https://stackoverflow.com/questions/4695902/asp-net-mvc-3-action-filters-and-autofac-dependency-injection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!