WPF - MVVM - Кто отвечает за новое соединение DataProvider?

Я знаю, что это может быть вопрос "стиля кодирования", но в этот момент я действительно запутался. В настоящее время я пытаюсь следовать шаблону MVVM (ViewModel, Repository, Controller и т. Д.)

Но кто должен инициировать соединение с источником данных? Особенно, когда более одного контроллера требуется активное соединение?

Существует не так много возможностей - либо каждый контроллер сам открывает новое соединение, соответствующий ViewModel открывает соединение и передает его в репозиторий, который, в свою очередь, передает его своему контроллеру, либо соединение создается еще раньше (например, StartUp.cs).

Я знаю, что нет "идеального" решения, но я надеюсь получить некоторое вдохновение и, возможно, хорошую / лучшую практику.

Обновление 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
 }
}

2 ответа

Решение

Я думаю, что вы путаете MVC с MVVM:

Обзор MVVMОбзор MVC

ViewModel отвечает за получение информации из модели, используя репозитории, которые получают данные из базы данных, вам не нужен контроллер здесь.

 public ViewModel()
    {
       Person.PersonRepository pR;
       Department.DepartmentRepository dR;
     }

Или еще лучше внедрить интерфейс репозитория в вашу ViewModel, чтобы получить чистую, отделенную и тестируемую реализацию:

public ViewModel(IPersonRepository personRepo, IDepartmentRepository depRepo)
    {
       Person.PersonRepository pR = personRepo;
       Department.DepartmentRepository dR = depRepo;
     }

Я думаю, что вы неправильно понимаете шаблон MVVM. Прочитайте эту статью:

https://msdn.microsoft.com/en-us/magazine/dd419663.aspx

Это должно помочь лучше понять MVVM.

ОБНОВИТЬ:

Хранилище открытого соединения. Если вы используете ORM для доступа к базе данных (EF, NHibernate), они обычно используют пул соединений. Если вы не используете ORM, вы можете реализовать пул.

http://martinfowler.com/eaaCatalog/repository.html - в этой статье описывается шаблон "Репозиторий". Он реализован как коллекционный интерфейс и должен скрывать особенности доступа к данным. Следовательно внутри хранилища должно быть создано соединение.

Другие вопросы по тегам