パイプラインのパターン


エラー処理を行うパイプラインパターンを実装して、より洗練されたパイプラインソリューションの作業を開始しましょう.
パイプライン実装の追加要件を定義しましょう
  • これは、断続的な流れを定義することができます.
  • これは、キューからメッセージを読み取るためのステップを定義することができます.
  • これは、別のキューにメッセージを送信する手順を定義することができます.
  • メッセージを送信した後に終了する.
  • それは応答を受信した後、特定のステップから継続することができます.
  • 下の図では、希望する流れ図を見つけることができます.

    'メッセージ'ステップの目的は、キューからメッセージを読むことです.つまり、この特定のパイプステップにメッセージを配送しなければなりません.つまり、キューからのメッセージが定義されたパイプモデルの一部であることを確認しなければなりません.これを確認するには、このようなプロパティを含むインターフェイスを作成します.
    public interface IInQueuePipeModel
    {
        string InMessage { get; set; }
    }
    
    フローダイアグラムで見ることができるように、異なるキューからメッセージを読み込むために複数の' in - message 'ステップを定義することが可能です.どのように、パイプラインは特定の待ち行列のために起動されるべきであるかを知っていますか?
    キューからメッセージを受信したり、キューにメッセージを送信するには、キュー名を知る必要があります.キュー名はここでキーです、そして、これは全く異なるメッセージのステップの区別に使用されることになっていることです.必要なことは二つあります.
  • パイプモデルに存在するキュー名は、どのキューメッセージが受信されたかを知るためのものです.
  • キューの名前は特定の' in - in 'メッセージのために定義されるので、パイプラインはどこでパイプ実行の出発点であるかについて理解することができます.
  • パイプモデルでキュー名定義を強制するにはQueueName プロパティIInQueuePipeModel インタフェース
    public interface IInQueuePipeModel
    {
        string QueueName { get; set; }
        string InMessage { get; set; }
    }
    
    また、'メッセージ'ステップのための別のインターフェイスが必要です.適切な手順でキュー名の存在を確保します.
    public interface IInQueuePipeStep<TPipeModel> : IPipeStep<TPipeModel> where 
    TPipeModel : IInQueuePipeModel
    {
        string InQueueName { get; }
    } 
    
    注意:ジェネリック型制約をTPipeModel , 型パラメータの意味TPipeModel 実装IInQueuePipeModel インターフェイス.
    最後の部分は'アウトメッセージ'ステップです.このステップはいくつかの外部キューに対するリクエストメッセージの準備に使用されます.さらに、このステップの後、パイプは応答を受け取るまで終了されるでしょう.
    そのためには、パイプラインのブレークポイントを示す' out message 'ステップのための特定のインターフェースが必要です.
    public interface IOutQueuePipeStep<TPipeModel> : IPipeStep<TPipeModel> where TPipeModel : IInQueuePipeModel
    { 
    }
    
    また、もう一つのインターフェースを導入しましたので、必要に応じて、パイプモデルは発信メッセージのプロパティを実装します.
    public interface IOutQueuePipeModel
    {
        string OutMessage { get; set; }
    }
    
    IOutQueuePipeModel インターフェイスが不要です.メッセージの送信を実装する方法が異なるので、パイプモデルでは必ずしもそのようなプロパティは必要ありません.あなたがそれを利用すると確信するとき、それを加えてください.
    パイプライン全体がワンピースとして定義されていても、実行時に複数の実行に分割されます.言い換えれば、特定の実行のために必要であるステップだけを抽出する場所のメカニズムがあるでしょう.それを達成する方法?既に定義されているインターフェイスを利用しましょう.IInQueuePipeStep and IOutQueuePipeStep . また、新しいQueuePipeService が導入され、キューに関連したパイプの実行に責任があります.
    以下の実装を見つけることができますQueuePipeService . 前の実装と比較する唯一の違いはExecuteAsync メソッド:
    public class QueuePipeService<TPipeModel> : IPipeService<TPipeModel>
    {
        protected readonly IList<Func<IPipeStep<TPipeModel>>> _pipeSteps;
    
        protected QueuePipeService()
        {
            _pipeSteps = new List<Func<IPipeStep<TPipeModel>>>();
        }
    
        public IPipeService<TPipeModel> Add(Func<IPipeStep<TPipeModel>> pipeStep)
        {
            _pipeSteps.Add(pipeStep);
            return this;
        }
    
        public async Task ExecuteAsync(TPipeModel pipeModel)
        {
            var steps = GetInitializedSteps().SkipUntil(s => !(s is IInQueuePipeStep<TPipeModel> && (s as IInQueuePipeStep<TPipeModel>).InQueueName == pipeModel.QueueName))
                                             .TakeUntil(s => !(s is IOutQueuePipeStep<TPipeModel>));
    
            foreach (var pipeStep in steps)
            {
                await pipeStep.ExecuteAsync(pipeModel);
            }
        }
    
        private IEnumerable<IPipeStep<TPipeModel>> GetInitializedSteps()
        {
            return _pipeSteps.Select(s => s.Invoke());
        }
    }
    
    ExecuteAsync それが手順を見つけるまでの方法で働くIInQueuePipeStep そのようなステップのためのインタフェースとキュー名はパイプモデルで通過される待ち行列名に等しいです.すべての次の手順を取得しますIOutQueuePipeStep , このステップの後にいくつかの要求メッセージが送られて、パイプラインが応答を受け取るまで終了されるということを示します.この機能を達成するためにIEnumerable 拡張メソッド:SkipUntil and TakeUntil .
    私が以前に述べたように、両方に共通のコードがたくさんあります.QueuePipeService and PipeService . (原則を自分で繰り返さないでください)、下に従うことthis link , 最終的な実装を抽出することができますPipeServiceBase 両方のサービスに共通の実装を含む抽象クラスです.
    最終的な実装に基づきます.PipelinePattern NuGet パッケージが生成されます.これはダウンロードして使用する準備が整いました.

    概要
    提案されたパイプ実装を使用して、全体のビジネスプロセスを1つの場所で定義することができます.さらに、複雑なビジネスフローの実装は、きれいで、堅実で、テスト可能で、コードを理解しやすいでしょう.実装の詳細を知ることなく、パイプのステップだけを見て、一見したところ、特定のパイプラインで何が起こるかは全く明らかです.それはすべてを見つけるために特定のステップに掘るだけの問題です.また、あなたのパイプラインにログを統合する場合は、簡単に追跡することができます.
    あなたがプロジェクトでそれを利用することを願っています.
    あなたは' Pipelinepattern 'を入力してnugetパッケージマネージャでそれを見つけることができます.

    将来の強化
    たとえばパイプラインソリューションに組み込むことができます.
  • 一連のステップの並列実行
  • signalrによるパイプライン進展の報告
  • ステイ!