2013-03-03 42 views
6

將此作爲基礎APIController使用,思考?大部分即時通訊好奇的處理處置的SaveChanges,主場迎戰ExecuteAsync方法我已經在別處見到過......使用WebAPI和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; } 

} 

回答

12

爲了管理會話對象的生命週期上我更喜歡用行動篩選器屬性基礎API控制器。請看下面的代碼演示其這種做法:

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

看起來不錯,我給它一個鏡頭。 – 2013-03-04 14:57:24

+0

@FitzchakYitzchaki:爲什麼我想在問題中使用這個而不是(更容易看)的方法? *(注意:我是一個Web API **和RavenDB初學者,所以有可能我錯過了一些東西)* – 2013-04-21 19:38:49

+1

因爲它將功能封裝在屬性中而不是將其添加到基本控制器。這使基本控制器更加乾淨。 – 2013-04-22 06:11:34