LoginSignup
1
1

More than 3 years have passed since last update.

NPocoの紹介 -機能編- インターセプター

Posted at

NPocoの紹介 -機能編- インターセプター

最初の記事はこちら

今回はインターセプターについて紹介します。

ソースはこちら

インターセプターについて

各処理の前や後に処理を組み込むためのものです。

基底のインターフェースとしてIInterceptor が用意されており、組み込みポイント毎にさらに継承したインターフェースが用意されています。

登録するには?

インターセプターを登録するにはDatabase.Interceptors プロパティに実装クラスのインスタンスを追加します。

using Database database = new Database(con);
database.Interceptors.Add(new LoggingInterceptor());

次に各インターセプターの紹介をします。

IExecutingInterceptor

クエリの実行前、実行後に呼び出されます

私はクエリのロギングのために使っています。

public class LoggingInterceptor : IExecutingInterceptor
{
    public void OnExecutedCommand(IDatabase database, DbCommand cmd)
    {
        var fmtCmd = ((Database)database).FormatCommand(cmd);
        //実運用ではコンソールではなくILogger<>を使っている
        Console.WriteLine(fmtCmd);
    }

    public void OnExecutingCommand(IDatabase database, DbCommand cmd)
    {
        //noop
    }
}

IConnectionInterceptor

コネクションが開いた、閉じたときに呼ばれるようです(使ったことない)

IExceptionInterceptor

例外発生時に呼ばれます。

例外ログを残したり、
一意制約違反判定を行い一意制約違反であれば別例外にラップしてスロー

といった使い方を私はしています。

IDataInterceptor

クエリ自動生成によるInsert, Update, Delete時に呼ばれます。
false を返すと実行を中止します。

私は共通列への値のセットを行うために使っています。

//共通列を定義した基底クラスを用意
//各エンティティクラスはこれを継承
public abstract class AbstractEntity
{
    [Column("created_at")]
    public DateTime? CreatedAt { get; set; }

    [Column("updated_at")]
    public DateTime? UpdatedAt { get; set; }
}
  public class CommonColumnInterceptor : IDataInterceptor
  {
      public bool OnDeleting(IDatabase database, DeleteContext deleteContext)
      {
          return true;
      }

      public bool OnInserting(IDatabase database, InsertContext insertContext)
      {
          if (insertContext.Poco is AbstractEntity aEntity)
          {
              DateTime now = DateTime.Now;
              aEntity.CreatedAt = now;
              aEntity.UpdatedAt = now;
          }
          return true;
      }

      public bool OnUpdating(IDatabase database, UpdateContext updateContext)
      {
          if (updateContext.Poco is AbstractEntity aEntity)
          {
              DateTime now = DateTime.Now;
              //更新対象列指定時のUpdateがうまくいかないので
              //それに対応するには別途拡張した仕組みを用意する必要があります。
              aEntity.UpdatedAt = now;
          }
          return true;
      }
  }

ITransactionInterceptor

トランザクションの開始、コミット、ロールバックで呼ばれるようです。(使ったことない)

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1