我刚开始学习 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>();
}
}
所以当你导出 Teacher
和 Student
来自 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/