ASP.NET MVC простой и распространённый инструмент. Но строить на его основе большое веб-приложение не так просто. Туториалы не раскрывают проблем возникающих при росте проекта. Зачастую, изначально стройная архитектура размазывается с каждой следующей итерацией.
Я хочу поделиться своим опытом. Рассказать об основных проблемах и предложить выбранные мной решения.
2. О себе
Веб-разработка около 4х лет
ASP.NET MVC более 3х лет
Благодаря ASP.NET влюбился в платформу .NET
Люблю выпить и поговорить про архитектуру :)
2
3. О чем доклад?
Архитектура MVC
Организация бизнес логики приложения
Повторное использование кода
Немного о модульном тестировании
Обработка исключительных ситуаций
3
14. public ActionResult GetByTagAndDate( string tagName, DateTime date,
string authorName)
{
...
ViewBag.IsTroll = true;
return View(posts);
}
14
Потенциальное падение во время исполнения
15. Проверка на стороне представления
@{
var troll = false;
if (ViewBag.IsTroll != null)
troll = (bool)ViewBag.IsTroll;
}
@if (troll) {
<p>Ты мерзкий тролль!!!</p>
}
15
16. Последствия
1. Бизнес-логика в контроллерах
2. Использование динамической типизации для передачи данных
представлению
3. Навешивание на бизнес-сущность атрибутов валидации
16
17. public class User_Entity {
[Required]
[StringLength(100)]
[Remote("CheckUserName", "Account")]
public string Name { get; set; }
[Required]
[SecurePassword]
public string Password { get; set; }
}
17
18. public class User_Entity {
[Required]
[StringLength(100)]
[Remote("CheckUserName", "Account")]
public string Name { get; set; }
[Required]
[SecurePassword]
public string Password { get; set; }
}
18
19. Последствия
1. Бизнес-логика в контроллерах
2. Использование динамической типизации для передачи данных
представлению
3. Навешивание на бизнес-сущность атрибутов валидации
4. Использование одной модели для отображения и получения
данных
19
36. АМ / БМ
Анемичная модель (бедная модель)
Сущности представляют данные
Сущности это плоские классы
Богатая модель
Единый язык между разработчиком и специалистом
Модель это дистиллированное знание
36
48. DAL / Рекомендации
Persistence Ignorance
Сущности не должны зависеть от способа хранения данных
Использование паттерна Repository
Более гибкое решение:
Использование CQRS
48
58. 58
Вынос JS кода из представлений
App.views.Posts.Troll = ( function () {
// private scope
return {
init: function () {
// public API
}
}
})(jQuery);
60. Проблема HTTP 1.0 / 1.1
Дополнительные расходы на установку
соединения для каждого запроса
Конвейерная передача HTTP
Параллельные HTTP соединения в современных
браузерах от 4 до 8
60
61. Проблема HTTP 1.0 / 1.1
Дополнительные расходы на установку
соединения для каждого запроса
Конвейерная передача HTTP
Параллельные HTTP соединения в современных
браузерах от 4 до 8
61
62. Минификация
Объединение JS в один
файл при помощи bundle
62
public class BundleConfig {
public static void RegisterBundles(
BundleCollection bundles) {
bundles.Add(new ScriptBundle("~/scripts/jquery")
.Include("~/Scripts/jquery-{version}.js")
.Include("~/Scripts/PostsTroll.js"));
}
}
63. Минификация
Объединение JS в один
файл при помощи bundle
Использование
сторонних сборщиков
gulp
grunt
...
63
public class BundleConfig {
public static void RegisterBundles(
BundleCollection bundles) {
bundles.Add(new ScriptBundle("~/scripts/jquery")
.Include("~/Scripts/jquery-{version}.js")
.Include("~/Scripts/PostsTroll.js"));
}
}