Это один из способов сделать это.
Альтернатива, с которой я столкнулся:
Создайте файл edmx, удалите пользовательский инструмент, чтобы он не генерировал сущности автоматически.
Откройте файл edmx, щелкните правой кнопкой мыши и добавьте элемент генерации кода - перейдите к онлайн-шаблонам в базе данных и выберите генератор макетов EF POCO. Это создает два шаблона T4 (один для сущностей и другой для контекста объекта и контекста фиктивного объекта).
Один шаблон T4 сгенерирует ваши сущности poco для вас. Другой шаблон T4 создаст интерфейс, который вы можете расширить для использования в качестве единицы работы, которая реализована в реальном контексте объекта и в контексте фиктивного объекта. Для его расширения необходимо изменить шаблон T4, включив в созданный интерфейс дополнительный метод (void SaveChanges ()) и реализацию этого метода в контексте фиктивного объекта.
Я нашел, что это работает очень хорошо.
Несмотря на то, что в целях модульного тестирования вы не захотите проверять свою единицу работы (если только проверка / добавление / удаление определенных объектов и т. Д.). Вместо этого вы будете тестировать репозитории с предопределенными обязанностями - обычно определенными в контексте (например, при назначении пациентам).
Вы бы сделали что-то вроде этого:
public class PatientAppointmentRepository : IPatientAppointmentRepository
{
//Injected via IOC in constructor
private readonly IUnitOfWork _unitOfWork;
private readonly IPatientAppointmentLogic _patientAppointmentLogic;
public void CreateAppointment(PatientAppointmentModel model)
{
var appointment = ModelMapper.Instance.To<PatientAppointment>(model);
var appointmentAdded = _patientAppointmentLogic.Add(appointment);
if(appointmentAdded)
_unitOfWork.SaveChanges();
}
}
public class PatientAppointmentLogic : IPatientAppointmentLogic
{
private readonly IUnitOfWork _unitOfWork; //Set via constructor
private readonly PatientLogic _patientLogic;
public bool Validate(PatientAppointment appointment)
{
if(appointment == null)
throw new ArgumentNullException("appointment");
//perform some logic here
return true;
}
public void Add(PatientAppointment appointment)
{
if(appointment == null)
throw new ArgumentNullException("appointment");
if(!Validate(appointment)) return; //Or throw an exception, up to you
var patient = _patientLogic.GetById(appointment.PatientId);
if(patient == null) return;
patient.PatientAppointments.Add(appointment);
}
}
Это действительно ваше дело, чтобы структурировать это соответствующим образом. Вы могли бы иметь другой репозиторий AppointmentLogic, который имеет базовую проверку в качестве примера.
В идеале общая проверка не должна зависеть от внешних ресурсов (таких как база данных).
Вы должны иметь возможность создать контекст проверки одним махом, который будет использоваться для дальнейшей проверки (сначала действует «дешево», прежде чем проверять «дорого»).
Иногда все «значения», которые вам нужны для проверки, находятся внутри сущности, которая вам в любом случае понадобится, а затем используйте ее в качестве контекста проверки.
Удачи!