DbContext注入WCF服务

时间:2014-03-01 09:22:46

标签: c# wcf entity-framework

我想问你我的想法是否会运作良好。

我最近开始使用Entity Framework和WCF。在我当前的项目中,我希望每个服务都是原子的,也就是说一个服务在一个事务中。但我不想为所有服务操作多次编写相同的事务相关代码。然后我认为交易及其错误处理是在一个地方IOperationInvoker完成的,就像下面显示的代码片段一样。

这个技巧的优点是我可以实例化DbContext或使用块创建事务,这样它们肯定可以处理服务中发生的任何事情。我只需处理一次与db相关的异常。

似乎有效。但我担心这是否是使用IOperationInvoker和EF的合法方式。

有任何缺点吗?

// service base class
public abstract MyBaseService
{
    DbContext database {get; set;}
}

[ServiceContract]
public interface IMyService {...}

// concrete service class
public class MyService : MyBaseService, IMyService {...}

public class MyOperationInvoker : IOperationInvoker
{
    IOperationInvoker originalOperationInvoker; // to be set at construction

    public object Invoke(object instance, object[] inputs, out object[] outputs)
    {
        using (var dbContext = new MyDbContext())
        {
            // inject DbContext into my service to be used in it.
            (MyServiceBase)instance.database = dbContext;

            // invoke a service within db transaction.
            using (var transaction = dbContext.Database.BeginTransaction())
            {
                try
                {
                    objct ret = originalOperationInvoker.invoke(instance, inputs, outputs);
                    transaction.Commit();
                    return ret;
                }
                catch (Exception e)
                {
                    transaction.Rollback();
                    throw;
                }
            }
        }
    }
    ...
}

2 个答案:

答案 0 :(得分:2)

使用操作调用程序时:是的,您可以执行此操作。这是在WCF中为传入呼叫添加“包装逻辑”的主要场所。请注意,对于异步方法,您需要实现一组不同的接口方法。

关于自动事务管理:我发现隐式事务不足,因为您需要控制隔离级别和超时设置。此外,有时您需要多个交易。也许不是在第一个版本,但最终你会超过这个计划。

我最近成功做的是在一个单元中创建一个类包装 DbContext和一个事务。我的大多数WCF方法都是这样的:

void SomeMethod() {
 using (var db = new MyDatabaseContext(isolationLevel, timeout, connectionString, ...)) {
  //custom body that uses the wrapped DbContext
  db.CompleteTransaction();
 }
}

这里有一些代码重复,但它并不太糟糕,我仍然可以完全控制我如何使用数据库。我可以为每个方法使用多个事务,嵌套它们或使用运行时计算的超时值。没有什么神奇的东西(就像一个隐含的操作调用者)。它也是例外安全。

答案 1 :(得分:2)

另一个想法是拥有一个自定义实例提供程序。实例提供程序允许您通过提供创建和释放实例的显式点来控制wcf服务实例的生存期。

通过将其与ioc容器相结合,您可以将上下文自动注入服务,然后在请求完成时处理。

我最近在博客上发表了这篇文章,请参阅我的博客文章了解技术细节。

http://www.wiktorzychla.com/2014/02/lifetime-management-of-wcf-services.html