Я унаследовал приложение ASP.NET, построенное на основе веб-форм, и приложение страдает от того, что вся его бизнес-логика встроена в код. В результате это приложение не может быть проверено модулем.
Я хочу разбить функциональность каждой формы на стиль MVC, но я обнаружил, что ASP.NET сопротивляется всем моим усилиям по его рефакторингу. В общем, я люблю разделять свои классы MVC следующим образом:
public class LoginModel
{
public string Username, Password;
public bool IsAuthenticated;
}
public interface ILoginView
{
event Action UserLoggedIn;
void SetMode(bool isAuthenticated);
}
public class LoginController
{
ILoginView View;
LoginModel Model;
public LoginController(ILoginView view, LoginModel model)
{
this.View = view;
this.Model = model;
// hook onto view events
}
}
После того, как мои классы настроены и хорошо протестированы, я могу реализовать интерфейс ILoginView
в моем пользовательском контроле или на странице:
public class LoginView : UserControl, ILoginView
{
public LoginView() : base()
{
new LoginController(this); // registers view with the controller
}
}
Если бы это было приложение winform, оно бы работало красиво. Но жизненный цикл ASP.NET приводит к нарушению этого стиля.
ASP.NET создает и уничтожает представление при каждой загрузке страницы. Поскольку мой контроллер удерживается представлением, модель удерживается контроллером, при каждой обратной передаче моя страница теряет свое состояние.
Я могу устранить описанную выше проблему, удерживая мой контроллер в сеансе пользователей, но это создает массу проблем. В частности, размещение контроллеров в сеансе вызывает проблемы с памятью, поскольку модели и контроллеры не возвращаются при сборке мусора до истечения сеанса. Переход от страницы к странице создает десятки контроллеров, но контроллеры не избавляются от себя, когда пользователь уходит со страницы.
Так как представление уничтожается / воссоздается при каждой обратной передаче, мне приходится заново регистрировать представление в контроллере при каждой обратной передаче. Это сложнее, чем кажется, потому что состояние модели нужно копировать обратно в представление при каждой обратной передаче, но одновременно мы не хотим перезаписывать изменения пользователя в представлении, которые были сделаны в предыдущей обратной передаче. Вы не представляете, к какому дополнительному кошмару это приводит при работе с динамически созданными или AJAXed элементами управления, использующими этот стиль MVC.
Я знаю, что обдумываю это, и есть более простой способ получить желаемые результаты, но как правильно реализовать стиль MVC с помощью веб-форм?