2013-03-03 26 views
6

Bunu bir temel APIController olarak kullanma, düşünceler? Çoğunlukla Revize içinde SaveChanges ele merak im, vs üzerine oturumu nesnenin yaşam döngüsünü yönetmek için ben başka bir yerde gördüğüm ExecuteAsync yöntemi ...WebAPI ve RavenDB ile temel oturum yönetimi

using System; 
using System.Net.Http; 
using System.Threading; 
using System.Threading.Tasks; 
using System.Web.Http; 
using System.Web.Http.Controllers; 
using Raven.Client; 
using Raven.Client.Document; 

public abstract class RavenDbController : ApiController 
{ 
    private IDocumentStore _documentStore; 

    public IDocumentStore Store 
    { 
     get { return _documentStore ?? (_documentStore = LazyDocStore.Value); } 
     set { _documentStore = value; } 
    } 

    protected override void Initialize(HttpControllerContext controllerContext) 
    { 
     Session = Store.OpenSession(); 
     base.Initialize(controllerContext); 
    } 

    protected override void Dispose(bool disposing) 
    { 
     using (Session) 
     { 
      Session.SaveChanges(); 
     } 
    } 

    public IDocumentSession Session { get; set; } 

} 

cevap

12

Ben bir eylem filtre özelliğini kullanmayı tercih temel API denetleyicisi.

public class RavenSessionManagementAttribute : ActionFilterAttribute 
{ 
    private readonly IDocumentStore store; 

    public RavenSessionManagementAttribute(IDocumentStore store) 
    { 
     if (store == null) throw new ArgumentNullException("store");  
     this.store = store; 
    } 

    public override void OnActionExecuting(HttpActionContext actionContext) 
    { 
     var controller = actionContext.ControllerContext.Controller as AbstractApiController; 
     if (controller == null) 
      return; 

     // Can be set explicitly in unit testing 
     if (controller.RavenSession != null) 
      return; 

     controller.RavenSession = store.OpenSession(); 
     controller.RavenSession.Advanced.UseOptimisticConcurrency = true; 
    } 

    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 
    { 
     var controller = actionExecutedContext.ActionContext.ControllerContext.Controller as AbstractApiController; 
     if (controller == null) 
      return; 

     using (var session = controller.RavenSession) 
     { 
      if (session == null) 
       return; 

      if (actionExecutedContext.Exception != null) 
      { 
       session.SaveChanges(); 
      } 
     } 
    } 
} 

FilterConfig.cs:

public class FilterConfig 
    { 
     public static void RegisterGlobalFilters(HttpFilterCollection filters) 
     { 
      filters.Add(new RavenSessionManagementAttribute(DocumentStoreHolder.Store)); 
     } 
    } 

AbstractApiController.cs: Bu yaklaşımı ispat aşağıdaki kodu Bkz

public abstract class AbstractApiController : ApiController 
    { 
     public IDocumentSession RavenSession { get; set; } 
    } 
+0

harika görünüyor, ben de denemek gerekir. –

+0

@FitzchakYitzchaki: Neden bu soruyu (daha kolay görünen) yaklaşım yerine kullanmak isterdim? * (Not: Ben bir Web API'sı ** ve ** RavenDB başlangıççıyım, bu yüzden bir şeyleri kaçırmam mümkün olabilir) * –

+1

Bu, bir temel denetleyiciye eklemek yerine bir öznitelikteki işlevselliği kapsüllediği için. Bu, baz kontrol cihazını daha temiz tutar. –