使用Autofac在WCF服务中实现工作单元

时间:2012-04-03 06:57:47

标签: wcf autofac unit-of-work

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

使用Autofac的wcf集成,可以轻松地将每个调用(或Autofac术语LifetimeScope)工作单元的相同实例注入到我的服务和存储库中 - 我所追求的是一种在返回时提交工作单元更改的方法如果没有任何例外,显然只能进行WCF服务调用。

我见过Using a Custom Endpoint Behavior with WCF and Autofac,这基本上就是我的开始,但不涉及异常。

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

1 个答案:

答案 0 :(得分: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中删除。