Di lapisan domain saya memiliki kelas:
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 dilindungi internal. Ini disengaja, yang menghasilkan Id adalah database dan harus ReadOnly.
Namun pada test layer, harus memiliki akses ke setter property ini.
Jadi di lapisan domain saya menambahkan atribut di AssemblyInfo.cs:
[assembly: InternalsVisibleTo("MyTestLayer")]
Ini akan memungkinkan saya untuk mengatur Id di lapisan tes tetapi tidak di lapisan domain!
Dalam lapisan uji
Telepon baru().Id = 1; // Bekerja!!
Di lapisan UI
Telepon baru().Id = 1; // Tidak dikompilasi! Tidak berfungsi!
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();
Secara teoritis, kode di atas seharusnya berfungsi, tetapi ketika tes jalan saya terjadi kesalahan:
Properti "Id" bersifat hanya-baca.
Semua properti Id
s adalah protected internal
.
Dalam file yang sama, tes yang sama dapat melakukan sesuatu seperti:
Telepon baru().Id = 1; // Bekerja!!
Email baru().Id = 1; // Bekerja!!
Ini dengan jelas memberi tahu Anda bahwa Anda memiliki _abstraksi bocor_ dalam Model Domain Anda. Model Domain tidak boleh dirancang dengan mempertimbangkan teknologi batas tertentu.
Masalah khusus ini dengan sangat jelas memberi tahu Anda bahwa Model Domain Anda _tidak_ dapat digunakan kembali.
InternalsVisibleTo
tidak berpengaruh karena hanya mengizinkan akses ke perpustakaan pengujian Anda, tetapi AutoFixture adalah rakitan yang sama sekali berbeda. Ini hanya memberi tahu Anda bahwa _no_ klien lain akan dapat menggunakan kembali Model Domain Anda.
Tindakan terbaik adalah mempertimbangkan kembali desain API Anda. Biasanya, saya akan melakukan sesuatu seperti ini:
``` c#
Telepon kelas umum : IEntity
{
Telepon publik (int id)
{
this.Id = id;
}
public virtual int Id { get; private set; }
public virtual string Tipo { get; set; }
public virtual string Numero { get; set; }
}
```
Ini menghasilkan banyak diskusi dalam kelompok arsitektur yang saya ikuti.
Ada masalah besar dengan pendekatan ini:
max (id) + 1
dan kemudian mengatur Id objek saya. Tetapi bagaimana cara mengatur Id jika hanya bisa dibaca?Setuju bahwa ini semua adalah _problems_. Keempatnya _sangat_ menunjukkan bahwa Model Domain bergantung pada lapisan persistensi, dan tidak dapat berfungsi tanpanya.
Saya mengerti masalahnya. Saya tidak dapat mengubah tipe PK menjadi Guid, akan benar-benar berfungsi.
Saya mengerti sekarang bahwa masalahnya tidak terkait dengan AutoFixture, tetapi jika Anda tertarik. Saya membuat proyek sampel untuk membahas ini.
Terima kasih.