私のドメインレイヤーには次のクラスがあります。
public class Telefone : IEntity
{
public virtual int Id { get; protected internal set; }
public virtual string Tipo { get; set; }
public virtual string Numero { get; set; }
}
IDは内部で保護されています。 これは意図的なものであり、IDを生成するのはデータベースであり、読み取り専用である必要があります。
ただし、テストレイヤーでは、このプロパティのセッターにアクセスできる必要があります。
そのため、私のドメインレイヤーでAssemblyInfo.csに属性を追加しました。
[assembly: InternalsVisibleTo("MyTestLayer")]
これにより、テストレイヤーでIDを設定できますが、ドメインレイヤーでは設定できません。
テストレイヤー内
new Telefone()。Id = 1; //動作します!!
UIレイヤー内
new Telefone()。Id = 1; //コンパイルしません! 動作しません!
var pessoa = fix.Build<Pessoa>()
.With(p => p.Nome)
.Do((pess) =>
{
fix.Build<Telefone>()
.With(p => p.Id)
.With(p => p.Tipo)
.With(p => p.Numero)
.OmitAutoProperties()
.CreateMany(10).ToList().ForEach(pess.Telefones.Add);
fix.Build<Email>()
.With(p => p.Id)
.With(p => p.Tipo)
.With(p => p.Endereco)
.OmitAutoProperties()
.CreateMany(10).ToList().ForEach(pess.Emails.Add);
})
.OmitAutoProperties()
.Create();
理論的には、上記のコードは機能するはずですが、私のロードテストでエラーが発生します。
プロパティ「Id」は読み取り専用です。
すべてのプロパティId
はprotected internal
です。
同じファイルで、同じテストで次のようなことができます。
new Telefone()。Id = 1; //動作します!!
new Email()。Id = 1; //動作します!!
これは、ドメインモデルに_リークのある抽象化_があることを明確に示しています。 ドメインモデルは、特定の境界テクノロジーを念頭に置いて設計するべきではありません。
この特定の問題は、ドメインモデルが再利用できないことを非常に明確に示しています。
InternalsVisibleTo
は、テストライブラリへのアクセスのみを許可するため効果はありませんが、AutoFixtureはまったく別のアセンブリです。 これは、他のクライアントがドメインモデルを再利用できるようになることはないということを示しています。
最善の行動は、API設計を再検討することです。 通常、私は次のようなことをします:
`` `c#
パブリッククラスTelefone:IEntity
{{
public Telefone(int id)
{{
this.Id = id;
}
public virtual int Id { get; private set; }
public virtual string Tipo { get; set; }
public virtual string Numero { get; set; }
}
`` `
これは、私がフォローしているアーキテクチャのグループで多くの議論を引き起こしました。
このアプローチには大きな問題があります。
max (id) + 1
ような操作を行ってから、オブジェクトのIDを設定します。 しかし、読み取り専用の場合、IDを設定するにはどうすればよいですか?これらはすべて_問題_であることに同意しました。 それらの4つすべては、ドメインモデルが永続層に依存しており、それなしでは機能させることができないことを_強く_示しています。
私は問題を理解しています。 PKタイプをGuidに変更することはできませんが、実際に機能します。
問題はAutoFixtureに関連していないことを理解しましたが、興味があれば。 これについて議論するためのサンプルプロジェクトを作成し
ありがとう。