Not sure the title accurately represents my question, sorry about that.
I have three projects: Persistence, Core (logic) and Test, set up like so (some stuff omitted for brevity):
Persistence
public struct PatientData
{
public int? ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public interface IPatientRepository : IDisposable
{
IEnumerable<PatientData> GetPatients();
PatientData GetPatientByID(int patientID);
void InsertPatient(PatientData patient);
void DeletePatient(int patientID);
void UpdatePatient(PatientData patient);
void Save();
}
class PatientRepositoryEF : IPatientRepository, IDisposable
{
// assume EF implementation here
}
public static class Factory
{
public static IPatientRepository GetPatientRepository() {
// not ideal, will refactor later
// assume EF for now
return new PatientRepositoryEF();
}
}
Core
public class Patient
{
// CTORS/DTORS
public Patient() {
this.repository = Persistence.Core.Factory.GetPatientRepository();
}
public Patient(Persistence.Core.IPatientRepository repository) {
// for testability, haven't actually used...
this.repository = repository;
}
~Patient() {
if (repository != null) {
repository.Dispose();
}
}
// PERSISTENCE
private Persistence.Core.IPatientRepository repository;
public void Fill(int patientID) {
Persistence.Core.PatientData data = repository.GetPatientByID(patientID);
this.ID = data.ID;
this.FirstName = data.FirstName;
this.LastName = data.LastName;
}
public void Save() {
repository.Save();
}
// other domain stuff
}
Test
static void Main(string[] args) {
Patient p = new Patient();
p.Fill(1546);
// test that data fills ok
}
This all works fine, but I thought to dump that public Fill method and set up a public constructor to take an ID so consumers can either a) create a new/empty Patient, or b) pass an ID through the ctor to fill the model accordingly. Figure these changes:
add new CTor to Core.Patient and privatize fill():
public Patient(int patientID) {
this.repository = Persistence.Core.Factory.GetPatientRepository();
fill(patientID);
}
void fill(int patientID) { /* fill method here */ }
change test project to this:
static void Main(string[] args) {
Patient p = new Patient(1546);
// test that data fills ok
}
Now, where the test project worked perfectly before (with p.Fill
exposed), I can no longer compile the test project without a reference to the Persistence project (you must add a reference to assembly 'Persistence')
This isn't a major issue, I can work around it, but thought it'd be nice to bury that Fill() method. I'm guessing that this is has something to do with dependency visibility when objects are constructed, but on the other hand it runs the parameterless constructor from the test project just fine without the test project requiring the persistence reference.
I'm not clear on why this reference would be required with the only change being param vs. paramless construction. Can someone explain?
Edit: The exact error is:
The type 'Persistence.Core.IPatientRepository' is defined in an assembly that is not referenced. You must add a reference to assembly 'Persistence, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
If I replace Patient p = new Patient(1546);
with Patient p = new Patient()
, all is well.
Thanks