将RavenDB与ServiceStack一起使用

编程入门 行业动态 更新时间:2024-10-09 23:11:59
本文介绍了将RavenDB与ServiceStack一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我阅读了Phillip Haydon的这篇帖子,内容涉及在ServiceStack中使用NHibernate/RavenDB. 每当我需要这样的数据库内容时,我都看不到获取IDocumentStore和打开新会话的意义:

I read this post by Phillip Haydon about how to use NHibernate/RavenDB with ServiceStack. I don't see the point about getting the IDocumentStore and open new session every time i need something from the db like this:

public class FooService : ServiceBase<Foo> { public IDocumentStore RavenStore{ get; set; } protected override object Run(ProductFind request) { using (var session = RavenStore.OpenSession()) { // Do Something... return new FooResponse{/*Object init*/}; } } }

为什么我不能为每个请求只使用一个会话,而当请求结束时,请根据响应状态提交更改或将其回滚?

Why cant i just use one session per request and when the request is ended, commit the changes or roll them back according to the response status?

如果我的方法很好,那我该怎么执行呢? 这是我的尝试:

If my approach is fine, than how can i implement it? here is my attempt:

我创建了此类:

public class RavenSession : IRavenSession { #region Data Members private readonly IDocumentStore _store; private IDocumentSession _innerSession; #endregion #region Properties public IDocumentSession InnerSession { get { return _innerSession ?? (_innerSession = _store.OpenSession()); } } #endregion #region Ctor public RavenSession(IDocumentStore store) { _store = store; } #endregion #region Public Methods public void Commit() { if (_innerSession != null) { try { InnerSession.SaveChanges(); } finally { InnerSession.Dispose(); } } } public void Rollback() { if (_innerSession != null) { InnerSession.Dispose(); } } #endregion #region IDocumentSession Delegation public ISyncAdvancedSessionOperation Advanced { get { return InnerSession.Advanced; } } public void Delete<T>(T entity) { InnerSession.Delete(entity); } public ILoaderWithInclude<object> Include(string path) { return InnerSession.Include(path); } public ILoaderWithInclude<T> Include<T, TInclude>(Expression<Func<T, object>> path) { return InnerSession.Include<T, TInclude>(path); } public ILoaderWithInclude<T> Include<T>(Expression<Func<T, object>> path) { return InnerSession.Include(path); } public T Load<T>(string id) { return InnerSession.Load<T>(id); } public T[] Load<T>(params string[] ids) { return InnerSession.Load<T>(ids); } public T Load<T>(ValueType id) { return InnerSession.Load<T>(id); } public T[] Load<T>(IEnumerable<string> ids) { return InnerSession.Load<T>(ids); } public IRavenQueryable<T> Query<T, TIndexCreator>() where TIndexCreator : AbstractIndexCreationTask, new() { return InnerSession.Query<T, TIndexCreator>(); } public IRavenQueryable<T> Query<T>() { return InnerSession.Query<T>(); } public IRavenQueryable<T> Query<T>(string indexName) { return InnerSession.Query<T>(indexName); } public void Store(dynamic entity, string id) { InnerSession.Store(entity, id); } public void Store(object entity, Guid etag, string id) { InnerSession.Store(entity, etag, id); } public void Store(object entity, Guid etag) { InnerSession.Store(entity, etag); } public void Store(dynamic entity) { InnerSession.Store(entity); } #endregion }

现在我的服务如下:

public class FooService : ServiceBase<Foo> { public IRavenSession RavenSession { get; set; } protected override object Run(ProductFind request) { // Do Something with RavenSession... return new FooResponse {/*Object init*/}; } }

但是我仍然需要找到一种方法来知道何时结束提交/回滚更改的请求. 我发现的最好方法是使用ResponseFilters:

but i still need to find a way to know when the request is ended for commit/rollback the changes. the best way i found is by using ResponseFilters:

public class AppHost : AppHostBase { public AppHost() : base("", typeof (Foo).Assembly, typeof (FooService).Assembly) { } public override void Configure(Container container) { // Some Configuration... this.ResponseFilters.Add((httpReq, httpResp, respnseDto) => { var currentSession = (RavenSession) this.Container.Resolve<IRavenSession>(); if (!httpResp.IsErrorResponse()) { currentSession.Commit(); } else { currentSession.Rollback(); } }); // Some Configuration... } }

我确信有更好的方法可以做到这一点,但是如何呢?

I am sure that there is a better way to do this but how?

推荐答案

我刚刚将其包含在AppHost的Configure方法中

I just included this on the Configure method for the AppHost

var store = new DocumentStore() { Url = "127.0.0.1:8080", DefaultDatabase = "Test" }.Initialize(); container.Register(store); container.Register(c => c.Resolve<IDocumentStore>().OpenSession()).ReusedWithin(ReuseScope.Request);

您可以将其放在模块上并对其进行初始化.

You can put it aside on module and initialize it.

然后在您的服务中只需添加一个接受IDocumentSession的构造函数

Then in your services just add a constructor that accepts IDocumentSession

public HelloService : Service { private readonly IDocumentSession session; public HelloService(IDocumentSession session) { this.session = session; } }

你很好.

更多推荐

将RavenDB与ServiceStack一起使用

本文发布于:2023-11-25 20:22:40,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1631219.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:RavenDB   ServiceStack

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!