C#でアスペクト指向でロギングを実現する方法
C#でアスペクト指向的な方法でロギングする方法が無いかを調査した資料
備忘録なので、抜け漏れ多めだと思います。
調査のきっかけ
C#でWindowsFormアプリを作るうえでロギングを行う必要が出た
要件としては関数の実行の最初と最後に実行履歴を残すだけの単純なものだったため
アスペクト指向の考えを利用してログを残すことができないかを調査することにした
調査して分かった実現方法
- 自前でコードを書いて実現する
RealProxyというC#の用意したクラスを利用することで実現が可能となる
詳しくは以下
https://qiita.com/KoKeCross/items/4b16ff8cdad65e0fea23 - PostSharpを利用する
有料のPostSharpというライブラリが存在する
Community版もあり、機能制限はかかるが無料で使用することも可能
https://www.postsharp.net/get/community - Fodyを使用する
オープンソースのライブラリ(MITライセンス)
Fody自体はビルド時にC#,VBコードから生成されるIL(中間言語)
に対していろんなコードを追加することが簡単になるライブラリ
https://github.com/Fody/Home
Fodyを利用したアドインとして以下のようなものがある
https://github.com/Fody/Home/blob/master/pages/addins.md
アドインの中には特定のAttributeを付けた関数に対しては、関数の実行前後にログを仕込む
などができるアドインが存在する。(AnotarやMethodDecoratorなど)
比較
メリット・デメリット
自前でコードを書いて実現する
メリット
- .net frameworkのバージョンに縛られにくい
割と昔からあるクラスを利用するため、.net frameworkのバージョンがだいぶ古くても動作する - 処理の流れを制御しやすい
自前で実装する分、より柔軟にコーディングができる
別のライブラリとも組み合わせやすいと思われる
デメリット
- デバッグが大変
以下のURLに書いてある通り、デバッグが大変になる。
https://qiita.com/KoKeCross/items/4b16ff8cdad65e0fea23
PostSharpを利用する
メリット
- 実績のある商用のライブラリである
いろんな企業で使用されているため、実績がある
また、商用であるためちゃんとしたサポートもある模様 - 多機能である
商用版であれば、ロギングにかかわらずいろんな機能が搭載されている
etc. 引数に対してrequired修飾を行うことで引数の入力チェックを自動で実装する
デメリット
- 商用版を使う場合、費用がかかる
どれぐらいかかるかは以下のページ参照
https://www.postsharp.net/pricing/framework
ただし、この件は使用する機能を限定するのであればCommunity版を使うことで回避可能かもしれない - 学習コストが少し高い
メリットと表裏一体だが、多機能ゆえに学習コストが少し高くなる - 実行環境によっては動かない可能性がある
詳しくは以下
https://doc.postsharp.net/requirements
Fodyを使用する
メリット
- オープンソースである
オープンソースなため、費用無しで利用することが可能
(ライセンスはMITライセンス) - 開発が継続されている
2021年12月時点で開発が継続されて開発が行われている
そのため、何かのバグ・欲しい機能が無いなどがあっても将来の開発で修正・実装が入る可能性がある - アドインが豊富
Fody自体はILに対して操作を行うライブラリなのだが、それを拡張したアドインが多量に存在する
様々な機能がアドインで実装されているので、必要な機能だけを必要なだけ導入することが可能
https://github.com/Fody/Home/blob/master/pages/addins.md
デメリット
- 学習コストが少し高い
こちらもいろんな機能を利用しようとなると学習コストが高くなると思われる
Fody自体がILに手を加えるというライブラリであるため、何かしら起きた時のために
ある程度のILに対しての知識があると良い
結果
Fodyを利用することとする
採用基準としてはやはりオープンソースであることとアドインが豊富であること
お金がかからないというところでこのライブラリを使用することとする
実装自体もNugetでMethodBoundaryAspect.Fodyを入れて設定ファイルを定義し、
OnMethodBoundaryAspectを継承したAttributeを実装して「OnEntry」「OnExit」「OnException」
をオーバーライドするだけで簡単に実装することができた
余談
PostSharpのCommunity版の一部機能はFodyを使用しているらしく、それならばFodyで良いのではないかという判断もあった