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