在服务的dispose方法中处理DbContext

时间:2014-01-22 23:39:16

标签: servicestack

我的服务中有以下代码。当我向GET /posts

发出请求时,我收到以下错误消息

无法完成操作,因为已放弃DbContext

我应该如何处理DbContext?我可以在这里使用Service的Dispose方法,或者在什么情况下可以使用它?

public class PostsService : ServiceStack.Service
{
    BlogDbContext db = new BlogDbContext();

    public object Get(GetAllPosts req)
    {
        return db.Posts;
    }

    public override void Dispose()
    {
        if (db != null)
        {
            db.Dispose();
        }

        base.Dispose();
    }
}

1 个答案:

答案 0 :(得分:1)

无法重现:

不幸的是我无法重现你的问题,我的处理模式之后的简单测试成功了。

我创建了一个虚拟BlogDbContext

public class BlogDbContext : IDisposable
{
    public void DummyMethod()
    {
    }

    public void Dispose()
    {
        Console.WriteLine("Disposing BlogDbContext");
    }
}

然后我实施了一项测试服务,例如PostsService

[Route("/Test", "GET")]
public class TestRequest : IReturnVoid {}

public class TestController : Service
{
    BlogDbContext db = new BlogDbContext();

    public void Get(TestRequest request)
    {
        Console.WriteLine("Request use BlogDbContext");
        db.DummyMethod();
        Console.WriteLine("Finished using BlogDbContext");
    }

    public override void Dispose()
    {
        if(db != null)
            db.Dispose();

        base.Dispose();
    }
}

当我调用/Test路由时,不会抛出异常并且控制台输出:

  • 请求使用BlogDbContext
  • 使用BlogDbContext
  • 完成
  • 处置BlogDbContext

这会向我表明,BlogDbContext中存在一个问题,即您没有留下足够长的时间来使用。如果你不处理服务,你的BlogDbContext是否还活着?


依赖性注射

如果我正在实施该服务,我将利用ServiceStack的依赖注入See here for more information,并使用您的AppHost配置方法将数据库实例注入您的服务。请求结束后,系统会自动调用BlogDbContext的{​​{1}}方法。因此,您无需在服务中实施Dispose比听起来容易。

在AppHost中,添加到您的Configure方法:

override void Dispose

在您的服务替换中

public override void Configure(Funq.Container container)
{
    // This injects your Database Context, a fresh context for each request
    container.Register<BlogDbContext>(c => new BlogDbContext()).ReusedWithin(Funq.ReuseScope.None);
}

BlogDbContext db = new BlogDbContext();

它还使您的代码更容易进行测试。

如果您仍然发现它失败了,那么您的public BlogDbContext db { get; set; } ... // Remember to remove the: public override void Dispose() 肯定会出现问题。