Где мне разместить создание зависимостей для класса Presenter в архитектуре пассивного просмотра?
-
21-08-2019 - |
Вопрос
Я только что провел рефакторинг нового доменного класса из класса презентатора, но не могу понять, где его создать.
Это часть более масштабной продолжающейся работы по рефакторингу плохо поддерживаемого устаревшего проекта.
Presenter в настоящее время создается событием OnLoad представления, и представление передается в качестве параметра в конструктор.Все общедоступные методы в презентаторе не имеют параметров и возвращают void.Они взаимодействуют с представлением, используя общедоступные свойства представления.
Представление, будучи по сути своей скромной формой, во всем полностью зависит от ведущего.
Это типичный шаблон пассивного просмотра, и я бы хотел продолжать его придерживаться.Это подводит меня к моей дилемме.Мне нужно создать экземпляр моего нового объекта домена, который сможет использовать ведущий.
- Если я передам его через конструктор, представление должно будет его создать и получить ненужную зависимость.
- Если я создам его где-нибудь в презентаторе, я не смогу заменить его макетным объектом в своих модульных тестах.
- Если я сделаю это общедоступным свойством презентатора, я введу зависимость порядка создания от методов презентатора, в которых он используется, и я до сих пор не решил, какой внешний класс будет отвечать за его создание.
В настоящее время я не использую какие-либо фреймворки для внедрения зависимостей.Хотя я заинтересован в том, чтобы использовать его в будущем, исходный код все еще слишком хрупок, чтобы можно было использовать стороннюю структуру.
Я открыт для любых предложений.
Решение 2
Я нашел гораздо более простое решение.Вот пример моего исходного класса:
public Presenter(IView view)
{
this.View = view;
}
Я хотел передать свою новую зависимость в качестве аргумента конструктора, но не хотел также добавлять эту зависимость в свое представление.Конструктор спешит на помощь!
public Presenter(IView view):this(view, new Dependency()){}
public Presenter(IView view, IDependency dependency)
{
this.View = view;
this.Dependency = dependency;
}
Теперь рабочий код продолжает использовать исходный интерфейс, в то время как модульные тесты используют новый, передавая макеты как для представления, так и для зависимости.Если число зависимостей продолжит расти, потребуется некоторый рефакторинг, но на ближайшее время это идеальное решение.
Другие советы
Я это уже сделал!!!Посмотрите здесь в мой репозиторий.Мой выбор здесь - использовать конструктор...Удовлетворив самых жадных. Я уверен, что ведущий поднялся.В вашем случае вы можете предоставить конкретную реализацию зависимостей из представления.
веселиться :)
На данный момент я бы выбрал репозиторий или фабрику.Это можно будет проверить сразу.В будущем вы можете заменить его реализацию на библиотеку DI.
public class DomainObjectsRepository
{
/// <summary>
/// can not be instantiated, use <see cref="Instance"/> instead.
/// </summary>
protected DomainObjectsRepository()
{
}
static DomainObjectsRepository()
{
Instance = new DomainObjectsRepository();
}
public static DomainObjectsRepository Instance { get; set; }
public virtual ICustomerDao GetCustomerDao()
{
return new CustomerDao();
}
}
public class DomainObjectsRepositoryMock : DomainObjectsRepository
{
public override ICustomerDao GetCustomerDao()
{
return new CustomerDaoMock();
}
}