2013-03-03 7 views
6

これをベースAPIControllerとして使用すると、主に、私は上のセッションオブジェクトのライフサイクルを管理するために、アクションフィルタ属性を使用して好む...対私は他の場所で見てきた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

を配置でのSaveChangesの取り扱いについて興味イムベース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

は偉大に見えますが、私はそれに打撃を与えるだろう。 –

+0

@FitzchakYitzchaki:質問で(簡単に見える)アプローチの代わりにこれを使用したいのはなぜですか? *(注:私はWeb API **と** RavenDB初心者ですので、何か不足している可能性があります)* –

+1

これは、ベースコントローラに属性を追加するのではなく、属性をカプセル化するためです。これにより、ベースコントローラをより清潔に保ちます。 –

関連する問題