WPF - MVVM - 谁负责新的 DataProvider 连接?
WPF - MVVM - Who is responsible for a new DataProvider Connection?
我知道这可能是一个 "style of coding" 问题,但此时我真的很困惑。目前我正在尝试遵循 MVVM 模式(ViewModel、Repository、Controller 等)
但是应该由谁发起与数据源的连接呢?尤其是当多个 Controller 需要一个活动连接时?
没有那么多可能性 - 每个 Controller 本身打开一个新连接,相应的 ViewModel 打开连接并将其传递给存储库,存储库又将其传递给它的控制器 - 或者连接被实例化甚至更早(例如 StartUp.cs)。
我知道没有 "perfect" 解决方案,但我希望能得到一些启发,也许是一个好的/最佳实践。
更新 1
示例代码:
namespace Question {
class ViewModel {
Person.Person p;
Department.Department d;
Person.PersonRepository pR;
Department.DepartmentRepository dR;
// Here in the VM both classes (Person and Department) intersect - should I inject an instance of a "IDataProvider" from here into the Repositorys?
// If so, I'd have to pass it to the repository which has to pass it to it's controller.
}
}
namespace Question.Person {
class Person {
// Person Model
}
class PersonRepository {
// This class does whatever a repository does and delegates database query to it's controller
}
class PersonController {
// Or should the Controller itself instantiate a new "IDataProvider" ?
// This class needs a connection to the databse to execute querys
}
}
namespace Question.Department {
class Department {
// Department Model
}
class DepartmentRepository {
// This class does whatever a repository does and delegates database query to it's controller
}
class DepartmentController {
// This class needs a connection to the databse to execute querys
}
}
我认为你误解了 MVVM 模式。阅读这篇文章:
https://msdn.microsoft.com/en-us/magazine/dd419663.aspx
它应该有助于更好地理解 MVVM。
更新:
存储库打开连接。如果你使用ORM访问数据库(EF,NHibernate),他们通常使用连接池。如果你不使用 ORM 那么你可以实现池。
http://martinfowler.com/eaaCatalog/repository.html - 本文描述模式 "Repository"。他实现了类似集合的接口,并隐藏了数据访问的特性。因此,应在存储库中创建连接。
我认为您混淆了 MVC 和 MVVM:
ViewModel负责从模型中检索信息,使用从数据库中获取数据的存储库,这里不需要控制器。
public ViewModel()
{
Person.PersonRepository pR;
Department.DepartmentRepository dR;
}
甚至更好 inject a repository interface 进入您的 ViewModel 以获得干净、解耦和可测试的实现:
public ViewModel(IPersonRepository personRepo, IDepartmentRepository depRepo)
{
Person.PersonRepository pR = personRepo;
Department.DepartmentRepository dR = depRepo;
}
我知道这可能是一个 "style of coding" 问题,但此时我真的很困惑。目前我正在尝试遵循 MVVM 模式(ViewModel、Repository、Controller 等)
但是应该由谁发起与数据源的连接呢?尤其是当多个 Controller 需要一个活动连接时?
没有那么多可能性 - 每个 Controller 本身打开一个新连接,相应的 ViewModel 打开连接并将其传递给存储库,存储库又将其传递给它的控制器 - 或者连接被实例化甚至更早(例如 StartUp.cs)。
我知道没有 "perfect" 解决方案,但我希望能得到一些启发,也许是一个好的/最佳实践。
更新 1
示例代码:
namespace Question {
class ViewModel {
Person.Person p;
Department.Department d;
Person.PersonRepository pR;
Department.DepartmentRepository dR;
// Here in the VM both classes (Person and Department) intersect - should I inject an instance of a "IDataProvider" from here into the Repositorys?
// If so, I'd have to pass it to the repository which has to pass it to it's controller.
}
}
namespace Question.Person {
class Person {
// Person Model
}
class PersonRepository {
// This class does whatever a repository does and delegates database query to it's controller
}
class PersonController {
// Or should the Controller itself instantiate a new "IDataProvider" ?
// This class needs a connection to the databse to execute querys
}
}
namespace Question.Department {
class Department {
// Department Model
}
class DepartmentRepository {
// This class does whatever a repository does and delegates database query to it's controller
}
class DepartmentController {
// This class needs a connection to the databse to execute querys
}
}
我认为你误解了 MVVM 模式。阅读这篇文章:
https://msdn.microsoft.com/en-us/magazine/dd419663.aspx
它应该有助于更好地理解 MVVM。
更新:
存储库打开连接。如果你使用ORM访问数据库(EF,NHibernate),他们通常使用连接池。如果你不使用 ORM 那么你可以实现池。
http://martinfowler.com/eaaCatalog/repository.html - 本文描述模式 "Repository"。他实现了类似集合的接口,并隐藏了数据访问的特性。因此,应在存储库中创建连接。
我认为您混淆了 MVC 和 MVVM:
ViewModel负责从模型中检索信息,使用从数据库中获取数据的存储库,这里不需要控制器。
public ViewModel()
{
Person.PersonRepository pR;
Department.DepartmentRepository dR;
}
甚至更好 inject a repository interface 进入您的 ViewModel 以获得干净、解耦和可测试的实现:
public ViewModel(IPersonRepository personRepo, IDepartmentRepository depRepo)
{
Person.PersonRepository pR = personRepo;
Department.DepartmentRepository dR = depRepo;
}