2012-04-03 68 views
6

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

使用Autofac的wcf集成方式,将工作单元接口的每个调用(或Autofac条款LifetimeScope)注入到我的服务和存储库中很容易 - 我所追求的是一种提交工作单元更改的方法显然只有在没有任何例外的情况下才返回WCF服务调用。

我见过Using a Custom Endpoint Behavior with WCF and Autofac这基本上是我如何开始的,但并没有处理异常。

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

+0

假设我们在容器中注册了一个'IUnitOfWork'。我们怎样才能用它包装一个服务调用,如果没有发生异常,只调用'SaveChanges()'?或者我们必须在服务构造器中使用UoW吗? – jgauffin 2012-05-23 07:34:00

+0

当你说服务电话,你的意思是WCF服务电话?如果是的话,那么我上面提供的链接显示你如何做到这一点。唯一的问题是,如果在使用AutoFac时没有发生任何异常,我还没有找到一种只保存UoW的方法。 – 2012-05-29 09:50:24

+0

你自己说过了=)'我之后是一种在WCF服务调用返回时显然只有在没有任何异常时才提交工作单元更改的方法。这是困难的部分,我正在寻找。 – jgauffin 2012-05-29 10:44:43

回答

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的。

+1

即使该操作抛出异常,它是否提交更改? – jgauffin 2012-05-29 10:43:07

+0

@jgauffin它不应该像在服务调用中抛出异常一样,它会在_baseInvoker.Invoke(实例,输入,输出输出)调用中抛出,并且下面的所有代码都将被忽略。 – xelibrion 2012-08-23 04:47:59

相关问题