参数化构造函数需要引用项目

本文关键字:引用 项目 构造函数 参数 | 更新日期: 2023-09-27 18:23:56

不确定标题是否准确地代表了我的问题,很抱歉。

我有三个项目:持久性、核心(逻辑)和测试,设置如下(为了简洁起见,省略了一些内容):

持久性

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();
    }
}

核心

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
}

测试

    static void Main(string[] args) {
        Patient p = new Patient();
        p.Fill(1546);
        // test that data fills ok
    }

这一切都很好,但我想转储公共Fill方法,并设置一个公共构造函数来获取ID,这样消费者就可以a)创建一个新的/空的Patient,或者b)通过ctor传递一个ID来相应地填充模型。图中这些变化:

将新的CTor添加到Core.Patient并私有化fill():

    public Patient(int patientID) {
        this.repository = Persistence.Core.Factory.GetPatientRepository();
        fill(patientID);
    }
    void fill(int patientID) { /* fill method here */ }

将测试项目更改为:

    static void Main(string[] args) {
        Patient p = new Patient(1546);
        // test that data fills ok
    }

现在,在测试项目以前工作得很好的地方(公开了p.Fill),如果没有对Persistence项目的引用(您必须添加对程序集"Persistence"的引用),我就无法再编译测试项目

这不是一个大问题,我可以解决它,但我认为埋葬Fill()方法会很好。我猜这与构建对象时的依赖性可见性有关,但另一方面,它从测试项目中运行无参数构造函数很好,而测试项目不需要持久性引用。

我不清楚为什么需要这个引用,唯一的变化是参数与无参数构造。有人能解释一下吗?

编辑:准确的错误是:

类型"Persistence.Core.IPatientRepository"是在未引用的程序集中定义的。必须添加对程序集"Persistence,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"的引用。

如果我用Patient p = new Patient()替换Patient p = new Patient(1546);,一切都很好。

感谢

参数化构造函数需要引用项目

编辑:

this.repository = Persistence.Core.Factory.GetPatientRepository();行似乎导致了您的错误。您意识到名称空间Persistence.Core与您的项目Core不一样,对吧?听起来你有一个名称空间和/或引用问题,你只需要系统地追踪它。很难远程计算出这一点。


所有项目依赖项必须链接一次,并且不能超过一次(否则会出现可怕的循环依赖项编译错误)。因此,在您的情况下,Core项目必须具有对Persistence的正式引用,然后Test必须具有对Core的正式引用(但不具有对Persistence的正式引用)。如果Persistence必须在Core之外直接使用,那么您将需要通过Core公开它,或者考虑重构您的设计。

对于那些试图创建典型的3层体系结构而没有完成真正隔离第1层和第3层的全部工作的人来说,循环依赖性问题可能会令人沮丧。两种可能有帮助的技术是事件处理程序/回调方法和具有更多接口的重构。这两种技术都倾向于需要进行实质性的重构,这会很快激励人们在开始按键之前在设计阶段进行长时间的思考。

设置2层体系结构并不总是很糟糕(取决于特定的上下文),但如果您采用这种方式,强烈建议您合并业务逻辑和数据层。与存储层相比,Presentation层几乎总是会经历更频繁、更彻底的更改,因此选择该层作为隔离层是有意义的。