【问题标题】:Basic session handling with WebAPI and RavenDB使用 WebAPI 和 RavenDB 进行基本会话处理
【发布时间】:2013-03-03 23:10:59
【问题描述】:

使用它作为基础 APIController,想法?主要是我对处理 dispose 中的 savechanges 与我在其他地方看到的 ExecuteAsync 方法感到好奇......

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

}

【问题讨论】:

    标签: asp.net-web-api ravendb


    【解决方案1】:

    我更喜欢使用操作过滤器属性来管理基本 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; }
        }
    

    【讨论】:

    • 看起来不错,我试试看。
    • @FitzchakYitzchaki:为什么我要使用这个而不是问题中的(更容易看的)方法? (注意:我是 Web API RavenDB 初学者,所以我可能遗漏了一些东西)
    • 因为这将功能封装在一个属性中,而不是将其添加到基本控制器中。这使基本控制器更加干净。
    • 另外,您可能需要参考据说我听说 Ayende 为他的 Racoon 产品制作的 DocumentStoreHolder。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    • 2016-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-29
    • 2020-05-15
    相关资源
    最近更新 更多