2013-03-03 30 views
6

Sử dụng điều này làm cơ sở APIController, suy nghĩ? chủ yếu là im tò mò về xử lý SaveChanges trong dispose, so với phương pháp ExecuteAsync mà tôi đã nhìn thấy ở đâu đó ...Xử lý phiên cơ bản với WebAPI và RavenDB

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; } 

} 

Trả lời

12

Tôi thích sử dụng một thuộc tính lọc hành động để quản lý vòng đời của đối tượng session trên bộ điều khiển API cơ sở. Xem đoạn mã sau đó chứng minh phương pháp này:

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:

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

sẽ rất tốt, tôi sẽ cho nó một shot. –

+0

@ FitzchakYitzchaki: Tại sao tôi muốn sử dụng điều này thay vì cách tiếp cận (dễ nhìn) trong câu hỏi? * (Lưu ý: Tôi là một Web API ** và ** RavenDB mới bắt đầu, vì vậy nó có thể là tôi đang thiếu một cái gì đó) * –

+1

Bởi vì điều này đóng gói các chức năng trong một thuộc tính hơn là thêm nó vào một bộ điều khiển cơ sở. Điều này giúp bộ điều khiển cơ bản sạch sẽ hơn. –