c# - 如何确定为接口(interface)的不同实现调用哪个存储库?

标签 c# domain-driven-design ddd-repositories

我刚开始学习 DDD,对对象和存储库的接口(interface)有疑问。假设我有以下对象

public interface IPerson { ... }

public class Student 
{
    double gpa;
    ...
}

public class Teacher
{
    double salary; ...
}

然后我还有两个仓库比如

public class StudentRepository :IRepository { public void Save(Student) }

public class TeacherRepository :IRepository { public void Save(Teacher) }

我的问题是,假设我有一个名为 persons 的 IPerson 对象列表,有没有一种方法可以让我做类似 repository.Save(persons) 的事情?无需使用反射来确定 IPerson 实际是什么类型。

我现在还有一个类(class)

PersonRepository :IRepository 
{
     public void Save(IPerson person)
     {
          if(Person is Student)
          {
               new StudentRepository.Save(person as Student);
          }
          else if(Person is Teacher)
          { ....}
      }
}

然后我可以调用 personRepository.Save(persons); 然而,这感觉并不是构建事物的最佳方式。我怎样才能改进这个设计?

谢谢

编辑:

我正在寻找的是,假设我收到一个名为 person 的 IPerson 对象。我不一定知道它是什么实现,我只想调用 repository.Save(person) 并让它调用正确的存储库。有没有一种方法可以在不使用某种带反射的 switch 语句的情况下做到这一点?

最佳答案

考虑使用通用存储库

class Repository<T> :IRepository<T>
{
     public void Save(T entity)
     {
         ...
     }
}

用法

IRepository<Student> repo1 = new Repository<Student>();
repo1.Save(new Student());

IRepository<Teacher> repo2 = new Repository<Teacher>();
repo2.Save(new Teacher());


接下来,您可以使用 IoC 容器和 DI 来传递存储库而不是创建它们

顶层,在main 方法或global.asax

IRepository<Student> studentRepo = IoC.Current.Resolve<IRepository<Student>>();

稍后在需要保存数据的类中,传递IRepository<Student> studentRepo进入构造函数

class Foo
{
    private IRepository<Student> repo

    Foo(IRepository<Student> repo)
    {
        this.repo = repo;
    }

    public void Save(Student s)
    {
        repo.Save(s);
    }
}

编辑

您可以将保存操作移动到 IPerson<T>

class Person<T> : IPerson<T>
{
    private IRepository<T> repo;

    Person(IRepository<T> repo)
    {
        this.repo = repo;
    }

    public void Save()
    {
        repo.Save<T>();
    }
}

所以当你导出 TeacherStudent来自 Person<T>你路过通讯员T , 喜欢

class Student : Person<Student>
{
    private IRepository<Student> repo;

    Person(IRepository<Student> repo):base(repo)
    {
       ...
    }    
}

这将使您能够在没有反射的情况下使用 List 或切换功夫。

关于c# - 如何确定为接口(interface)的不同实现调用哪个存储库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11960460/

相关文章:

c# - 存储库作为工厂?

java - Spring Data 存储库实际上是如何实现的?

c# - asp.net objectdatasource 从控件和文本框传递参数

c# - 计算以避免数据库中出现负值

c# - RowDataBound 上的 Gridview 行的背景颜色在 IE11 中不起作用

POJO的Java设计理念

doctrine - Doctrine 2 中的多态关联?

c# - 是否有一种通用的 DDD 模式来处理域对象的欠载?

c# - 表格嵌套在 itextsharp 中的 PDFPCELL 中

mysql - SQL模式设计和规范化