前回はドメインプロジェクトのフォルダー構成のお話をしました。
今回はInfrastructure(インフラストラクチャー)プロジェクトのフォルダー構成を解説していきます。
Infrastructureとは?
インフラストラクチャーとは,作成するアプリケーションが,外部と接触している部分のコードのみを集める場所です。外部と接触している部分というのは,例えばテキストファイルを開いたり,CSVファイルを開いたり,データベースへアクセスすることです。
C#で作成したアプリケーションは最終的には「XX.exe」みたいな感じで実行ファイルになって実行されますが,多くの場合,外部と接触をします。「電卓アプリ」とかであれば,起動して,何かファイルを読み込んだり,書き込んだりという処理をしないかもしれませんが,もしも,アプリ終了後に「最後の値を記憶する」という仕様があるのであれば,それは何かしらの外部に記憶させる必要があります。そういったときに,多くの場合で「データベース」や「ファイル」が使われます。
それ以外にも,パソコンからパソコンに通信したり,何らかの機器と通信したりするような場合も,当然外部との接触という事になります。
なぜ外部との接触部分を集めるのか?
なぜ外部との接触部分を集める必要があるのか?というと,それには2つの理由があります。
外部の影響を局所的にする
外部と接触しているという事は,外部の影響を受けます。起動後どことも接触しない「電卓アプリ」であれば,好きに作成しても外部の影響は受けませんが,例えばSqlServerを使用している場合,SqlServerがバージョンアップすると,正しく動作しなくなる可能性があります。何かしらの修正が発生した場合,外部接触部分を局所化しておくと,修正が容易になります。ソリューションの至る所でSqlServerに接触していたら,コードの隅々までチェックしないと,対処できなくなります。なので,SqlServerに触れるところは極限まで限定的に接触させます。
テスト容易性
外部と接触している部分は「テストがやり辛い」という特性があります。例えば計測器と通信するパソコンソフトを作成する場合は,その「計測器がないとテストできない」という状況になります。その場合でも,容易にダミーデータを流し込めるような状況にすることで,テスト容易性が上がります。そのためにも外部接触部分を切り離して考えておく必要があります。
フォルダー構成
フォルダー構成としては,テクノロジーごとにフォルダーを分けるようにします。SqlServerを使用する場合は「SqlServer」で1つフォルダーを作成します。CSVを使用するなら「Csv」というフォルダーを作成し,外部と接触する部分のみ実装します。要するに,外部との通信ができない場合は,通信エラーになってしまうコードのみを記述します。そしてそれらは,ドメイン層のRepositoriesフォルダーに作成するインタフェースを使用します。
Fake
偽物のデータの事をFakeと呼んでいます。ダミーデータと思ってください。インタフェース越しに外部と接触することで,外部と接触する実装と,接触しないFakeモードでの接触を実装することで,外部データとの通信部分を容易にテストすることができます。SqlServerを使用する場合も,とりあえずFake実装をすることで,プロトタイプにもなるし,テスト容易性も上がります。
Factoryパターン
本番コードとFakeコードの切り替えがFactoryパターンを使用します。Factoryパターンとは,クラスを生成することだけをするクラスです。ここで,FactoryのみPublicで公開し,その他のInfrastructureのコードをInternalにすることで,Factory経由でしかアクセスできないように強制することができ,すべてのクラスが本番コード,もしくはFakeモードでの生成を強制できるようにして,一部だけFakeという誤った実行状態にならないようにすることができます。
#02_プロジェクトの追加
#03_依存関係
#04_ドメイン駆動開発でApplication層は必要?
#05_Domainのフォルダー構成
#06_Infrastructureのフォルダー構成
#07_WinFormのフォルダー構成
#08_Testsのフォルダー構成
#09_テスト駆動で実装するための事前準備
#10_テストコードとViewModelの追加
#11_テストコードを追加する
#12_ Repositoriesフォルダーの作成
#13_ Entitiesフォルダーの作成
#14_ Mockの作成
#15_フォーム画面の作成
#16_画面のコントロールデータバインドする
#17_Fakeを使ってタミーデータを画面に表示させる
#18_Fakeデータを画面に通知する
#19_PropertyChangedの方法を変更する
#20_Fakeとデータベースの値を切り替える方法
#21_Sharedクラスを作成する
#22_クラスを生成するファクトリークラスを作る
#23_#if DEBUGでFakeデータがリリースされないようにする
#24_DEBUGモードであることをわかりやすくしておく
#25_Factories以外から生成できないようにしておく
#26_Factoriesの呼び出しはViewModelで行う
#27_外部の設定ファイルの値で判断する
#28_Fakeデータを切り替える方法
#29_FakePathを設定ファイルとSharedに移す
#30_Fakeデータのバリエーション
#31_Shareクラスの活用方法
#32_ベースフォームを作る
#33_SharedにログインIDを記憶する
#34_BaseFormでログインユーザーを表示する
#35_ValueObject
#36_ValueObjectを作成する
#37_抽象クラスValueObjectを使用してイコールの問題の解消
#38_AreaIdにビジネスロジックを入れる
#39_AreaIdクラスをEntityに乗せる
#40_MeasureDateの作成
#41_MeasureValueの作成
#42_オブジェクト指向の自動化
#43_Repositoryの具象クラス
#44_例外処理
#45_例外の作成
#46_インナーエクセプション
#47_例外の欠点
#48_メッセージの区分
#49_エラー処理の共通化
#50_ログの出力
#51_タイマー処理はどこに置く?
#52_タイマークラスの作成
#53_StaticValues
#54_Logics
#55_Helpers
#56_Module
#57_トランザクションはどこでかける?
#58_特徴を見極める
#59_さいごに