UnitOfWork Attribute for WebAPI

In one of my previous post I mentioned the UnitOfWork concept and created an attribute for asp.net MVC which creates a transaction and wraps an entire request inside.  The MVC attribute closed it’s transaction after the view has rendered, this runs on the OnResultExecuted method.

In WebApi how ever there is no method that is fired after the response has been serialised. This may not seem like a problem; however, if you are returning a collection as IEnumerable<> from an ApiController or anything that lazily executes from you then then unit of work will closes it’s transaction BEFORE you’ve pulled back your data. So far the only way I’ve found to get around this problem is instead to return an IList<> which forces the execution.

Below is a the UniOfWork attribute I’ve been using for WebApi, it also rolls back the transaction if an exception occurs as oppose to the MVC way.

 

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
  public sealed class UnitOfWorkFilter : ActionFilterAttribute, IExceptionFilter
  {
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
      var unitOfWork = (IUnitOfWork)GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IUnitOfWork));

      unitOfWork.EndTransaction();
    }

    public override void OnActionExecuting(HttpActionContext actionExecutingContext)
    {
      var unitOfWork = (IUnitOfWork)GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IUnitOfWork));
      unitOfWork.BeginTransaction();
    }

    public Task ExecuteExceptionFilterAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
    {
      var unitOfWork = (IUnitOfWork)GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IUnitOfWork));
      unitOfWork.RollBack();
      return Task.Run(() => { }, cancellationToken);
    }
  }

One comment

  • luke
    November 10, 2015 - 9:43 pm | Permalink

    Consider this

    private IUnitOfWork _uow;

    public ValuesController(IUnitOfWork uow)
    {
    _uow = uow;

    }

    [UnitOfWorkFilter]
    public void Post(MyType mt)
    {
    //do things
    }

    Will the IUnitOfWork be the same object as its being injected or there will be two obejcts

  • Leave a Reply