В моем доменном слое есть класс:
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, является базой данных и должен быть ReadOnly.
Но в тестовом слое должен быть доступ к установщику этого свойства.
Итак, в моем слое домена добавлен атрибут в AssemblyInfo.cs:
[assembly: InternalsVisibleTo("MyTestLayer")]
Это позволит мне установить идентификатор на уровне тестов, но не на уровне домена!
В тестовом слое
новый Телефон (). Id = 1; // Работает!!
На уровне пользовательского интерфейса
новый Телефон (). 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
s равны protected internal
.
В том же файле тот же тест может делать что-то вроде:
новый Телефон (). Id = 1; // Работает!!
новый адрес электронной почты (). Id = 1; // Работает!!
Это ясно говорит вам о том, что в вашей модели предметной области есть «нечеткая абстракция». Модель предметной области не должна разрабатываться с учетом какой-либо конкретной граничной технологии.
Эта конкретная проблема очень ясно говорит вам, что ваша модель домена _не_ повторно используется.
InternalsVisibleTo
имеет никакого эффекта, потому что он разрешает доступ только к вашей тестовой библиотеке, но AutoFixture - это совершенно другая сборка. Это просто говорит вам, что _no_ другой клиент никогда не сможет повторно использовать вашу модель домена.
Лучше всего пересмотреть дизайн вашего API. Обычно я бы делал что-то вроде этого:
`` С #
открытый класс Telefone: IEntity
{
общедоступный телефон (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, если он доступен только для чтения?Согласились, что это все _проблемы_. Все четыре из них явно указывают на то, что модель предметной области зависит от уровня персистентности и не может работать без него.
Я понимаю проблему. Я не могу изменить тип ПК на Guid, действительно сработает.
Теперь я понимаю, что проблема не связана с AutoFixture, но если вам интересно. Я создаю образец проекта, чтобы обсудить это.
Благодарю.