2012-04-03 6 views
6

Autofacを使用したWCFサービスで作業単位パターンを実装するにはどうすればよいですか?Autofacを使用したWCFサービスでの作業単位の実装

Autofacのwcf統合を使用して、作業単位インタフェースの呼び出しごとに(またはAutofacという用語LifetimeScopeで)同じインスタンスを私のサービスとリポジトリに注入するのは簡単です。私は後で作業単位の変更をコミットする方法ですWCFサービスコールの復帰は明らかに例外がない場合にのみ行われます。

私はUsing a Custom Endpoint Behavior with WCF and Autofacを見ましたが、これは基本的にどのように始めたのですが、それは例外を処理しません。

現在、私はIOperationInvokerを呼び出し、Invokeで作業単位を開始し、例外がない場合にのみコミットします。このアプローチの問題は、私がメソッドの中で私の作業単位のインスタンスを解決する必要があることです。これは私のサービスとリポジトリに注入されたものとは異なるインスタンスをAutofacInstanceProviderで使用しています。

+0

私たちがコンテナに 'IUnitOfWork'を登録したとしましょう。どのようにしてサービスコールをラップし、例外が発生していない場合にのみ 'SaveChanges()'を呼び出すことができますか?または、サービスコンストラクタでUoWを使用する必要がありますか? – jgauffin

+0

サービスコールと言ったら、WCFサービスコールを意味しますか?はいの場合、私が上記で提供したリンクは、あなたがそれを行う方法を示しています。唯一の問題は、AutoFacを使用しているときに例外が発生していない場合、UoWのみを保存する方法をまだ見つけていないことです。 –

+0

あなたはそれを自分で言った。「私が後にしているのは、WCFサービスコールの復帰時に作業ユニットの変更をコミットする方法は、明らかに例外がない場合のみです。それは難しい部分で、私が探しているものです。 – jgauffin

答えて

1

ブラッドリー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>(); 

これは、周囲/現在/文脈LifetimeScopeのうち、UOWをつかみます。

+1

オペレーションが例外をスローした場合でも変更をコミットしませんか? – jgauffin

+0

@jgauffinサービスコール内に例外がスローされたように、_baseInvoker.Invoke(インスタンス、入力、出力)呼び出しでスローされ、その下のすべてのコードは無視されます。 – xelibrion

関連する問題