FakeとSqlSeverのクラスをFactoriesで切り替える方法をこれまで解説してきました。しかし,いくらIsFakeを使ってFakeモードで動作させているつもりでも,Factoriesクラスを使わずに,SqlSeverクラスを直接生成するようなコードを書く人が現れてしまうと,一部はFakeだけど,一部はSqlServerにつながっていた・・・という事態になりかねません。
何とかして,統一した制御をしたいものです。今回はそれをどうやってやるかというお話をします。
インフラストラクチャー層がPublicだとViewからSqlSeverクラスをNewできる
インフラストラクチャー層がpublicになっているとViewからでもViewModelからでもいくらでもFakeやSqlServerクラスを生成できてしまいます。次のように画面でコーディングされると,いくらIsFakeがTrueでも,SqlServerに接続されてしまいます。
private LatestViewModel _viewModel = new LatestViewModel(new MeasureSqlServer());
全体をFakeで動かしているつもりが,一部だけSqlSeverにつながってしまいます。
InfrastructureはAllInternalにしてFactoriesのみpublicにする
すべてのコードがFactoriesで生成するように強制するために,Infrastructureのクラスは基本的にInternalで作成し,FactoriesのみをPublicで公開するようにします。
そうすると,MeasureFakeやMeasureSqlServerクラスはFactoriesクラスを使わないと生成できなくなるため,直接Newする人はいなくなります。
MeasureFakeをInternalにする
using NDDD.Domain.Entities; using NDDD.Domain.Ripositories; using System; namespace NDDD.Infrastructure.Fake { internal sealed class MeasureFake : IMeasureRepository { public MeasureEntity GetLatest() { return new MeasureEntity(10, Convert.ToDateTime("2020/12/12 12:34:56"), 123.341f); } } }
MeasureSqlServerクラスをInternalにする
using NDDD.Domain.Entities; using NDDD.Domain.Ripositories; using System; namespace NDDD.Infrastructure.SqlServer { internal sealed class MeasureSqlServer : IMeasureRepository { public MeasureEntity GetLatest() { throw new NotImplementedException(); } } }
ViewやViewModelから直接Newできなる
InfrastructureのクラスをInternalにすると,直接Newしようとしてもコンパイルエラーとなります。これで,Factoriesクラスを使って生成するしかできなくなります。
このようにアクセス修飾子を調整することで,プログラマーへコーディングを強制できるようにし,悪いコードが入り込む可能性を排除することができます。