ドメイン駆動開発_フォルダー構成編_#25_Factories以外から生成できないようにしておく

当サイトではアフィリエイト広告を利用しています。

NDDD

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クラスを使って生成するしかできなくなります。

このようにアクセス修飾子を調整することで,プログラマーへコーディングを強制できるようにし,悪いコードが入り込む可能性を排除することができます。