2012-04-03 27 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