【问题标题】:Implementing unit of work in a WCF service with Autofac使用 Autofac 在 WCF 服务中实现工作单元
【发布时间】:2012-04-03 06:57:47
【问题描述】:

如何使用 Autofac 在 WCF 服务中实现工作单元模式?

使用 Autofac 的 wcf 集成很容易将工作单元接口的每次调用(或 Autofac 术语 LifetimeScope)的相同实例注入我的服务和存储库 - 我所追求的是一种在返回时提交工作单元更改的方法显然只有在没有任何异常的情况下才会调用 WCF 服务。

我见过Using a Custom Endpoint Behavior with WCF and Autofac,这基本上是我开始的方式,但不处理异常。

目前我拥有的是一个IOperationInvoker,它启动 Invoke 中的工作单元并仅在没有任何异常的情况下提交它。这种方法的问题是我需要在 Invoke 方法中解析我的工作单元实例,这给了我一个与使用 AutofacInstanceProvider 注入到我的服务和存储库中的实例不同的实例。

【问题讨论】:

  • 假设我们在容器中注册了一个IUnitOfWork。我们如何用它包装服务调用,如果没有发生异常,只调用SaveChanges()?还是我们必须在服务构造函数中取UoW?
  • 当你说服务调用时,你是指WCF服务调用吗?如果是,那么我上面提供的链接显示了您如何做到这一点。唯一的问题是,如果使用 AutoFac 时没有任何异常,我还没有找到仅保存 UoW 的方法。
  • 你自己说的 =) what I am after is a way to commit the unit of work changes on return of WCF service call obviously ONLY if there has not been any exceptions.。这是最难的部分,也是我正在寻找的。​​span>

标签: wcf autofac unit-of-work


【解决方案1】:

Bradley Boveinis 找到了解决此问题的方法。我们尚未对其进行彻底测试,但它似乎可以工作:

public class UnitOfWorkAwareOperationInvoker : IOperationInvoker
{
    private readonly IOperationInvoker _baseInvoker;

    public UnitOfWorkAwareOperationInvoker(IOperationInvoker baseInvoker)
    {
        _baseInvoker = baseInvoker;
    }

    public object[] AllocateInputs()
    {
        return _baseInvoker.AllocateInputs();
    }

    public object Invoke(object instance, object[] inputs, out object[] outputs)
    {
        var result = _baseInvoker.Invoke(instance, inputs, out outputs);
        var context = OperationContext.Current.InstanceContext.Extensions.Find<AutofacInstanceContext>();

        try
        {
            context.Resolve<IUnitOfWork>().Save();
        }
        catch (Exception ex)
        {
            var message = Message.CreateMessage(MessageVersion.Default, string.Empty);
            new ElmahErrorHandler().ProvideFault(ex, null, ref message);
            throw;
        }
        return result;
    }

    public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
    {
        return _baseInvoker.InvokeBegin(instance, inputs, callback, state);
    }

    public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
    {
        return _baseInvoker.InvokeEnd(instance, out outputs, result);
    }

    public bool IsSynchronous
    {
        get { return _baseInvoker.IsSynchronous; }
    }
}

关键在下面一行:

OperationContext.Current.InstanceContext.Extensions.Find<AutofacInstanceContext>();

这会将 UoW 从环境/当前/上下文 LifetimeScope 中提取出来。

【讨论】:

  • 即使操作抛出异常也不提交更改吗?
  • @jgauffin 它不应该,好像在服务调用中抛出异常,它将在 _baseInvoker.Invoke(instance, inputs, out outputs) 调用中抛出,并且下面的所有代码都将是忽略。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-15
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多