2011-01-14 13 views
6

Su ASP.NET MVC 2 Ho un ActionFilterAttribute chiamato [Transaction] che avvia una transazione di NHibernate prima di eseguire l'azione e si impegna o rotola indietro in seguito, a seconda che o non è stata lanciata un'eccezione. L'istanza ISession è HttpRequestScoped() e iniettata da Autofac. Sembra così e funziona benissimo:ASP.NET MVC 3, filtri di azione, e Autofac Dependency Injection

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

Fantastico. Seems to be a common pattern.

Negli ASP.NET MVC 3 note, vedo questo piccolo trafiletto in "Breaking Changes" (sottolineatura mia):

Nelle versioni precedenti di ASP.NET MVC, filtri d'azione sono state creato per richiesta tranne in alcuni casi. Questo comportamento non è mai stato un comportamento garantito, ma solo un dettaglio di implementazione e il contratto per i filtri era considerarli senza stato. In ASP.NET MVC 3, i filtri sono memorizzati nella cache in modo più aggressivo. Pertanto, qualsiasi filtro di azione personalizzato che memorizza in modo errato lo stato dell'istanza potrebbe essere danneggiato.

Oops.

  • Significa che sto hosed se eseguo l'aggiornamento a MVC 3?
  • Se i filtri di azione non sono più istanziati per richiesta, in che modo otterremo le dipendenze nell'ambito delle richieste nei nostri filtri azione?

Grazie per qualsiasi intuizione.

risposta

6

Ho appena posto una domanda simile sui forum di Google. ecco il link https://groups.google.com/forum/#!topic/autofac/a0qqp2b3WA8

ho avuto la risposta:

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


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

Quindi è possibile utilizzare l'iniezione di proprietà nei tuoi attributi.

+0

Sì, sembra che il commento della nota di rilascio si applichi all'impostazione predefinita in MVC, ma i contenitori IoC lo sostituiscono per fornire i propri comportamenti. –

2

Oh yuck .... Nicholas, potrebbe essere necessario memorizzare la tua ISession e Transaction in HttpContext.Items, che dovresti essere in grado di raggiungere tramite ActionExecutedContext/ActionExecutingContext (magari impostandolo nel gestore di eventi OnActionExecuting), invece di tenerli in istanza membri. Oppure, o puoi chiamare un ServiceLocator all'interno del tuo filtro per prenderli per te (anche tu schifo).

Ora devo andare a dare un'occhiata al codice MVC 3 e vedere se ho problemi simili!

Problemi correlati